F diff --git a/lex/lexer.c b/lex/lexer.c
--- a/lex/lexer.c
+++ b/lex/lexer.c
#define LEXER_C LEXER_C
/*asdf*/#include <lexer.h>
- char *well_known_locations_base[]={"./",NULL};
+ char *well_known_locations_base[]={"./","/usr/include/","/usr/include/x86_64-linux-gnu/",NULL};
void lex(struct Source_File *src,struct Translation_Data *translation_data)
{
struct token *current_token;
/*this is a hack*/
- /*lines start at 0 , this is 1 a directive at the start of the file can be processed correctly*/
- size_t last_line=1;
+ ssize_t last_line=-1;
while(src->src[src->where_in_src]!='\0')
{
-
+ if(has_new_errors(translation_data))
+ {
+ push_lexing_error("could not process",src,translation_data);
+ return;
+ }
current_token=get_next_token(src,&chonky[0],1);
if(current_token->type==KW_HASHTAG)
++src->which_column;
}
}
- ret=malloc(sizeof(struct token));
- ret->type=KW_NOTYPE;
- ret->data_size=0;
- ret->filename=src->src_name->filename;
+ if(best_state->type==KW_COMMENT || best_state->type==PKW_COMMENT)
+ {
+ ret=malloc(sizeof(struct token));
+ ret->type=KW_NOTYPE;
+ ret->data_size=0;
+ ret->filename=src->src_name->filename;
+ }else
+ {
+ ret=malloc(sizeof(struct token));
+ ret->type=best_state->type;
+ ret->data_size=current_size;
+ 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;
+ }
return ret;
}
struct token* copy_token(struct token *src)
*cpy=*src;
return cpy;
}
+
+ void delete_source_file(struct Source_File *src)
+ {
+ delete_source_name(src->src_name);
+ free(src);
+ }
+ void delete_source_name(struct Source_Name *name)
+ {
+ free(name->filename);
+ free(name->base);
+ free(name);
+ }
#endif
F diff --git a/lex/lexer.h b/lex/lexer.h
--- a/lex/lexer.h
+++ b/lex/lexer.h
void chomp(struct Translation_Data *translation_data);
enum KEYWORDS kw_get(struct Translation_Data *translation_data);
+
+ void delete_source_file(struct Source_File *src);
+ void delete_source_name(struct Source_Name *name);
#endif
F diff --git a/lex/preprocessing.c b/lex/preprocessing.c
--- a/lex/preprocessing.c
+++ b/lex/preprocessing.c
#include string
#include <qchar>
#define [ id(list) replacement
+ #undef [ id ]
#line number [string]
#if
#ifdef
#error
#
- these should be seperated from the ifs
#elif
#else
#endif
return;
case PKW_IF:
free(hold);
- //parse_preproc_if_line(src,translation_data);
+ parse_preproc_if_line(src,translation_data);
return;
- default:
+ case PKW_IFDEF:
+ free(hold);
+ parse_preproc_ifdef_line(src,translation_data);
+ return;
+ case PKW_IFNDEF:
+ free(hold);
+ parse_preproc_ifndef_line(src,translation_data);
+ return;
+ case PKW_UNDEF:
+ free(hold);
+ parse_preproc_undef_line(src,translation_data);
+ return;
+ case PKW_ENDIF:
+ free(hold);
+ push_lexing_error("unmatched endif",src,translation_data);
+ return;
+ case PKW_ELSE:
+ free(hold);
+ push_lexing_error("unmatched else",src,translation_data);
return;
+ case PKW_ELIF:
+ free(hold);
+ push_lexing_error("unmatched elif",src,translation_data);
+ return;
+ default:
/*TODO error*/
+ push_lexing_error("expected a preprocessing directive",src,translation_data);
+ return;
}
}
}else if(hold_token->type==KW_NOTYPE)
{
- push_lexing_error("empty define directive",src,translation_data);
+ //push_lexing_error("empty define directive",src,translation_data);
free(hold_token);
/*TODO destroy new define directive*/
/*TODO there is a memory leak here*/
- return ;
+ // return ;
}
/*push things*/
translation_data->tokens=hold_tokens;
/*push the directive into the macro map*/
Map_Push(translation_data->macros,macro_name->data,macro_name->data_size,new_macro);
- free(macro_name);
+ //free(macro_name);
+ chase_new_line(src,translation_data);
}
/*
Queue_Push(translation_data->tokens,macro_name);
}
}
+ void preproc_lex_first_part(struct Source_File *src,struct Translation_Data *translation_data)
+ {
+ struct Source_File temp_src;
+ struct token *hold_token;
+ char just_in_case;
+
+ temp_src=*src;
+ hold_token=preproc_find_else(src,translation_data,1);
+
+ temp_src.src_size=src->where_in_src;
+ just_in_case=src->src[src->where_in_src];
+ src->src[src->where_in_src]='\0';
+
+ lex(&temp_src,translation_data);
+
+ src->src[src->where_in_src]=just_in_case;
+
+ do
+ hold_token=preproc_find_else(src,translation_data,0);
+ while(hold_token && !has_new_errors(translation_data));
+
+ if(hold_token!=NULL)
+ {
+ push_lexing_error("could not find matching #else, #elif or #endif",src,translation_data);
+ }
+ }
+ /*
+ we have skipped the #if part so this could be used for elif
+ */
+ void parse_preproc_if_line(struct Source_File *src,struct Translation_Data *translation_data)
+ {
+ size_t hold_line;
+ struct Queue hold_tokens;
+ struct Queue *swap_tokens;
+ struct token *hold_token;
+ struct Scope *empty_scope;
+ struct AST *expression;
+ int result;
+
+ hold_line=src->which_row;
+ Queue_Init(&hold_tokens);
+ hold_token=get_next_token(src,&chonky[0],0);
+ empty_scope=get_normal_scope(NULL,EXTERN_SCOPE);
+
+ swap_tokens=translation_data->tokens;
+ translation_data->tokens=&hold_tokens;
+ while(hold_token->type!=KW_NOTYPE && hold_token->line==hold_line)
+ {
+ expand_macro(hold_token,src,translation_data);
+ hold_token=get_next_token(src,&chonky[0],0);
+ }
- struct token* preproc_find_else(struct Source_File *src,struct Translation_Data *translation_data)
+ /*NOTYPE*/
+ free(hold_token);
+
+ expression=parse_expression(translation_data,empty_scope);
+ result=evaluate_const_expression_integer(expression);
+
+ delete_ast(expression);
+ delete_scope(empty_scope);
+ translation_data->tokens=swap_tokens;
+
+ if(hold_tokens.size>0)
+ {
+ push_lexing_error("unexpected token",src,translation_data);
+ while(hold_tokens.size>0)
+ free(Queue_Pop(&hold_tokens));
+ }
+
+ if(has_new_errors(translation_data))
+ {
+ push_lexing_error("fatal error",src,translation_data);
+ return ;
+ }else
+ {
+
+ if(result)
+ {
+ preproc_lex_first_part(src,translation_data);
+ }else
+ {
+ hold_token=preproc_find_else(src,translation_data,0);
+ if(hold_token!=NULL && hold_token->type==PKW_ELIF)
+ {
+ //preproc_find_else(src,translation_data,0);
+ parse_preproc_if_line(src,translation_data);
+ }
+ else
+ {
+ preproc_lex_first_part(src,translation_data);
+ }
+ }
+
+ }
+
+ }
+ struct token* preproc_find_else(struct Source_File *src,struct Translation_Data *translation_data,char jump_before)
{
struct token *hold_token;
+ struct Source_File temp_src;
int indentation=1;
while(src->src[src->where_in_src]!='\0' && indentation)
{
/*BEWARE*/
goto_new_line(src,translation_data);
+ temp_src=*src;
/*END BEWARE*/
hold_token=get_next_token(src,&chonky[0],1);
case PKW_ELIF:
if(indentation==1)
{
+ if(jump_before)
+ *src=temp_src;
return hold_token;
}
else
}
}
/*BEWARE*/
- goto_new_line(src,translation_data);
+ //goto_new_line(src,translation_data);
/*END BEWARE*/
+ if(jump_before)
+ *src=temp_src;
return NULL;
}
+ void parse_preproc_ifdef_line(struct Source_File *src,struct Translation_Data *translation_data)
+ {
+ struct token *hold_token;
+ hold_token=get_next_token(src,&chonky[0],0);
+ if(hold_token==NULL || hold_token->type!=KW_ID)
+ {
+ push_lexing_error("expected an id here",src,translation_data);
+ chase_new_line(src,translation_data);
+ }else
+ {
+ if(Map_Check(translation_data->macros,hold_token->data,hold_token->data_size))
+ {
+ preproc_lex_first_part(src,translation_data);
+ }else
+ {
+ hold_token=preproc_find_else(src,translation_data,1);
+ if(hold_token!=NULL && hold_token->type==PKW_ELIF)
+ {
+ parse_preproc_if_line(src,translation_data);
+ }
+ else
+ {
+ preproc_find_else(src,translation_data,0);
+ preproc_lex_first_part(src,translation_data);
+ }
+ }
+
+ }
+ chase_new_line(src,translation_data);
+ }
+ void parse_preproc_ifndef_line(struct Source_File *src,struct Translation_Data *translation_data)
+ {
+ struct token *hold_token;
+ hold_token=get_next_token(src,&chonky[0],0);
+ if(hold_token==NULL || hold_token->type!=KW_ID)
+ {
+ push_lexing_error("expected an id here",src,translation_data);
+ chase_new_line(src,translation_data);
+ }else
+ {
+ if(!Map_Check(translation_data->macros,hold_token->data,hold_token->data_size))
+ {
+ preproc_lex_first_part(src,translation_data);
+ }else
+ {
+ hold_token=preproc_find_else(src,translation_data,1);
+ if(hold_token!=NULL && hold_token->type==PKW_ELIF)
+ {
+ parse_preproc_if_line(src,translation_data);
+ }
+ else
+ {
+ preproc_find_else(src,translation_data,0);
+ preproc_lex_first_part(src,translation_data);
+ }
+ }
+
+ }
+ chase_new_line(src,translation_data);
+ }
+ void parse_preproc_undef_line(struct Source_File *src,struct Translation_Data *translation_data)
+ {
+ struct define_directive *hold_macro;
+ struct token *id;
+
+ id=get_next_token(src,&chonky[0],0);
+ if(id->type!=KW_ID)
+ {
+ push_lexing_error("expected an id here",src,translation_data);
+ return;
+ }else
+ {
+ hold_macro=Map_Check(translation_data->macros,id->data,id->data_size);
+ if(hold_macro!=NULL)
+ {
+ delete_macro(hold_macro);
+ }
+ }
+ chase_new_line(src,translation_data);
+ }
+ void delete_macro(void *macro)
+ {
+ #define AS_MACRO(x) ((struct define_directive*)macro)
+ free(AS_MACRO(macro)->macro_name);
+ while(AS_MACRO(macro)->macro_tokens->size>0)
+ free(Queue_Pop(AS_MACRO(macro)->macro_tokens));
+ Map_Map(AS_MACRO(macro)->arguments,free);
+ free(macro);
+ #undef AS_MACRO
+ }
#endif
F diff --git a/lex/preprocessing.h b/lex/preprocessing.h
--- a/lex/preprocessing.h
+++ b/lex/preprocessing.h
#include <chonky.h>
#include <gcc_error.h>
#include <map.h>
+ #include <scope.h>
struct define_directive
{
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);
-
+ void parse_preproc_ifdef_line(struct Source_File *src,struct Translation_Data *translation_data);
+ void parse_preproc_ifndef_line(struct Source_File *src,struct Translation_Data *translation_data);
+ void parse_preproc_undef_line(struct Source_File *src,struct Translation_Data *translation_data);
/*preproc if stuff*/
- /*returns an else or elif token, or if it hits matching endif before that return NULL and goto following line*/
- struct token* preproc_find_else(struct Source_File *src,struct Translation_Data *translation_data);
+ /*returns an else or elif token, or if it hits matching endif before that return NULL*/
+ struct token* preproc_find_else(struct Source_File *src,struct Translation_Data *translation_data,char jump_before);
+ /*hack*/
+ void preproc_lex_first_part(struct Source_File *src,struct Translation_Data *translation_data);
/*define stuff*/
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);
+ void delete_macro(void *macro);
#endif
F diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
{
print_errors(stdout,program->errors);
}
+ delete_program(program);
return 1;
}else if(command_arguments->print_ast && !command_arguments->is_quiet)
{
+ delete_program(program);
return 0;
}
F diff --git a/misc/map.c b/misc/map.c
--- a/misc/map.c
+++ b/misc/map.c
void Map_Scour(Map *tree,void *str,size_t size,size_t *where,Map **final_node)
{
- for(where[0]=0,final_node[0]=tree;where[0]<size && final_node[0]->delta[((unsigned char*)str)[ where[0] ]]!=NULL;++where[0])
+ for(
+ *where=0,*final_node=tree;
+ *where<size && final_node[0]->delta[((unsigned char*)str)[ where[0] ]]!=NULL;
+ ++where[0]
+ )
{
(*final_node) = (*final_node)->delta[((unsigned char*)str)[*where]];
}
if(temp == size)
{
- if(tree->ID!=NULL)tree->ID=id;
+ assert(tree->ID==NULL);
+ tree->ID=id;
tree->is_final=1;
return;
}
for(temp;temp<size;++temp)
{
- Map_Init(tree=tree->delta[((unsigned char*)str)[temp]]=malloc(sizeof(Map)));
+ Map_Init(
+ tree=tree->delta[((unsigned char*)str)[temp]]=malloc(sizeof(Map))
+ );
}
tree->ID=id;
tree->is_final=1;
return tree;
}
+
for(temp;temp<size;++temp)
{
- Map_Init(tree=tree->delta[((unsigned char*)str)[temp]]=malloc(sizeof(Map)));
+ Map_Init(
+ tree=
+ tree->delta[((unsigned char*)str)[temp]]=
+ malloc(sizeof(Map))
+ );
}
tree->ID=id;
F diff --git a/misc/print.c b/misc/print.c
--- a/misc/print.c
+++ b/misc/print.c
}
ret=0;
- hold_translation_data=get_translation_data();
+ hold_translation_data=get_translation_data(NULL);
do
{
base_file=get_source_file(*base_source_names,this_directory);
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);
+ delete_source_file(base_file);
break;
}
fprintf(out,"\nTOKENS OF %s {\n",base_file->src_name->filename);
{
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));
+ delete_translation_data(hold_translation_data);
- 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)
fprintf(out,"ERROR!");return;
}
- assert(1==0);
+ assert(!"reached end of switch");
}
void print_denoted(FILE *out,struct Denoted *denoted)
{
fprintf(out,"typedef ");
print_token(out,((struct Denoted_Typedef*)denoted)->id);
fprintf(out," to ");
- print_type(out,((struct Denoted_Typedef*)denoted)->node->ID,0);
+ print_type(out,((struct Denoted_Typedef*)denoted)->type,0);
return;
case DT_Function:
print_token(out,((struct Denoted_Function*)denoted)->id);
F diff --git a/misc/stack.h b/misc/stack.h
--- a/misc/stack.h
+++ b/misc/stack.h
#ifndef GSTACK_H
#define GSTACK_H GSTACK_H
- #include<stdlib.h>//malloc free et alii
+ #include<stdlib.h>
typedef struct Stack Stack;
struct Stack
F diff --git a/parse/parse_declaration.c b/parse/parse_declaration.c
--- a/parse/parse_declaration.c
+++ b/parse/parse_declaration.c
Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Typedef*)hold));
}else if(hold->denotation==DT_Object)
{
- Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold,NULL));
+ struct AST_Object_Declaration *od;
+ od=get_object_declaration_tree((struct Denoted_Object*)hold,NULL);
+ Queue_Push(where_to_push,od);
+ if(get_and_check(translation_data,KW_EQ))
+ {
+ od->initializer=parse_initializer(translation_data,scope,od->object);
+ }
}else
{
/*TODO error*/
hold=check_ordinary(scope,(struct token*)translation_data->tokens->first->data);
if(hold!=NULL && hold->denotation==DT_Typedef)
{
- ret->pair->node=((struct Denoted_Typedef*)hold)->node;
- ret->pair->type=(struct Type*)ret->pair->node->ID;
+ ret->type=((struct Denoted_Typedef*)hold)->type;
chomp(translation_data);
return ret;
}
exit:
if(ret->specifier==TS_ENUM)
{
- get_enum_type(ret);
+ ret->type=(struct Type*)get_enum_type(ret);
}else if(ret->specifier==TS_STRUCT || ret->specifier==TS_UNION)
{
- get_struct_union_type(ret);
- }else if(ret->pair->type==NULL)
+ ret->type=(struct Type*)get_struct_union_type(ret);
+ }else if(ret->type==NULL)
{
- get_basic_type(ret);
+ ret->type=(struct Type*)get_basic_type(ret);
}
return ret;
}
enum KEYWORDS hold;
while(get_and_check(translation_data,KW_STAR))
{
- char is_constant=0,is_volatile=0;
+ base->type=(struct Type*)get_pointer_type(base->type);
while(1)
{
hold=kw_get(translation_data);
if(hold==KW_CONST)
{
- is_constant=1;
+ ((struct Type_Pointer*)base)->is_const=1;
}else if(hold==KW_VOLATILE)
{
- is_volatile=1;
+ ((struct Type_Pointer*)base)->is_volatile=1;
}else
{
break;
}
}
- get_pointer_type(base->pair,is_volatile,is_constant);
}
parse_direct_declarator(translation_data,scope,base);
{
if(get_and_check(translation_data,KW_CLOSE_SQUARE))
{
- get_array_type(base->pair,NULL);
+ base->type=(struct Type*)get_array_type(base->type,NULL);
}else
{
- get_array_type(base->pair,parse_expression(translation_data,scope));
+ base->type=(struct Type*)get_array_type(base->type,parse_expression(translation_data,scope));
if(!get_and_check(translation_data,KW_CLOSE_SQUARE))
{
/*TODO error*/
push_translation_error("']' expected",translation_data);
- get_type_error(base->pair);
+ base->type=(struct Type*)get_type_error(base->type);
return;
}
}
Queue_Init(parameters);
parse_paramenter_list(translation_data,function_prototype_scope,parameters);
- get_function_type(base->pair,parameters,function_prototype_scope);
+ base->type=(struct Type*)get_function_type(base->type,parameters,function_prototype_scope);
}else
{
{
/*unnamed bitfields are possible*/
struct Denoted_Object *obj;
- obj=(struct Denoted_Object*)get_denoted_object(NULL,SC_NONE,prototype->pair->type);
- get_type_bitfield(prototype->pair,parse_expression(translation_data,scope));
+ obj=(struct Denoted_Object*)get_denoted_object(NULL,SC_NONE,prototype->type);
+ obj->object->type=(struct Type*)get_type_bitfield(prototype->type,parse_expression(translation_data,scope));
return (struct Denoted*)obj;
}else
/*TODO error*/
push_translation_error("unexpedted id in abstract declarator",translation_data);
delete_denoted_prototype(prototype);
- ret=base->pair->type;
+ ret=base->type;
delete_denoted_base(base);
return ret;
}
delete_denoted_prototype(prototype);
- ret=base->pair->type;
+ ret=base->type;
delete_denoted_base(base);
return ret;
*/
struct AST* parse_initializer(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *base)
{
-
+ return parse_assignment_expression(translation_data,scope);
}
const const const const const const const const const const const const const const const const const const const const const const const char const const const constant;
F diff --git a/semantics/denoted.c b/semantics/denoted.c
--- a/semantics/denoted.c
+++ b/semantics/denoted.c
ret=malloc(sizeof(struct Denoted_Base));
ret->denotation=prototype->denotation;
ret->id=NULL;
- ret->pair=get_type_map_pair(prototype->pair->type,prototype->pair->node);
+ ret->type=prototype->type;
return ret;
}
struct Denoted_Typedef *ret;
ret=malloc(sizeof(struct Denoted_Typedef));
ret->denotation=DT_Typedef;
- ret->node=base->pair->node;
+ ret->type=base->type;
ret->id=base->id;
return (struct Denoted*)ret;
struct Denotation_Prototype *ret;
ret=malloc(sizeof(struct Denotation_Prototype));
ret->denotation=DT_Prototype;
- ret->pair=get_type_map_pair(NULL,types);
+ ret->type=NULL;
+ ret->node=types;
ret->storage_class=SC_NONE;
ret->specifier=TS_NONE;
ret->constraint=TC_NONE;
}
struct Denoted* extract_denoted(struct Denoted_Base *base,struct Denotation_Prototype *prototype,char allow_abstract)
{
- if(base->pair->type->specifier==TS_FUNC)
+ if(base->type->specifier==TS_FUNC)
{
if(base->id==NULL && !allow_abstract)
- {
- return get_denoted_error(get_denoted_function(NULL,((struct Type_Function*)base->pair->type)->return_type,prototype->function_specifier));
+ {
+ return get_denoted_error(get_denoted_function(NULL,((struct Type_Function*)base->type)->return_type,prototype->function_specifier));
}else
{
- return get_denoted_function(base->id,base->pair->type,prototype->function_specifier);
+ return get_denoted_function(base->id,base->type,prototype->function_specifier);
}
}else if(prototype->storage_class==SC_TYPEDEF)
{
{
if(base->id==NULL && !allow_abstract)
{
- return get_denoted_error(get_denoted_object(base->id,prototype->storage_class,base->pair->type));
+ return get_denoted_error(get_denoted_object(base->id,prototype->storage_class,base->type));
}else
{
- return get_denoted_object(base->id,prototype->storage_class,base->pair->type);
+ return get_denoted_object(base->id,prototype->storage_class,base->type);
}
}
}
}
void delete_denoted_prototype(struct Denotation_Prototype *prototype)
{
- free(prototype->pair);
free(prototype);
}
void delete_denoted_base(struct Denoted_Base *base)
{
- free(base->pair);
free(base);
}
+ void delete_denoted_wrapper(void *denoted)
+ {
+ delete_denoted(denoted);
+ }
#endif
F diff --git a/semantics/denoted.h b/semantics/denoted.h
--- a/semantics/denoted.h
+++ b/semantics/denoted.h
{
enum Denotation_Type denotation;
struct token *id;
- struct Type_Map_Pair *pair;
+ struct Type *type;
};
struct Denoted_Function
{
{
enum Denotation_Type denotation;
struct token *id;
- struct Map *node;
+ struct Type *type;
};
struct Denoted_Enum
struct Denotation_Prototype
{
enum Denotation_Type denotation;
- struct Type_Map_Pair *pair;
+ struct Type *type;
+ struct Map *node;
enum Storage_Class storage_class;
struct Denoted* get_denotation_prototype(struct Map *types);
+ void delete_denoted_wrapper(void *denoted);
void delete_denoted(struct Denoted *denoted);
void delete_denoted_error(struct Denoted_Error *error);
void delete_denoted_function(struct Denoted_Function *function);
F diff --git a/semantics/gcc_error.c b/semantics/gcc_error.c
--- a/semantics/gcc_error.c
+++ b/semantics/gcc_error.c
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));
+ if(translation_data->tokens->size==0)
+ {
+ get_translation_error(error_message,0,0,"");
+ }else
+ {
+ Queue_Push(translation_data->errors,get_translation_error_by_token(error_message,(struct token*)translation_data->tokens->first->data));
+ }
}
void push_lexing_error(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data)
}
+ void delete_translation_error(struct Translation_Error *translation_error)
+ {
+ free(translation_error);
+ }
#endif
F diff --git a/semantics/gcc_error.h b/semantics/gcc_error.h
--- a/semantics/gcc_error.h
+++ b/semantics/gcc_error.h
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);
+ void delete_translation_error(struct Translation_Error *translation_error);
#endif
F diff --git a/semantics/program.c b/semantics/program.c
--- a/semantics/program.c
+++ b/semantics/program.c
ret->translation_units=malloc(sizeof(struct Queue));
ret->source_files=malloc(sizeof(struct Queue));
ret->errors=malloc(sizeof(struct Queue));
+ ret->types=malloc(sizeof(struct Map));
Queue_Init(ret->translation_units);
Queue_Init(ret->source_files);
TODO rework*/
ret->externs=get_normal_scope(NULL,EXTERN_SCOPE);
+ Map_Init(ret->types);
+
return ret;
}
struct Source_File* extract_source_file(FILE *in,struct Source_Name *name)
{
- size_t file_size;
+ long file_size;
struct Source_File *src;
- fseek(in,0,SEEK_END);
- file_size=ftell(in);
- rewind(in);
+ if(fseek(in,0,SEEK_END)==-1)
+ return NULL;
+ if((file_size=ftell(in))==-1)
+ return NULL;
+ if(fseek(in,0,SEEK_SET)==-1)
+ return NULL;
src=malloc(sizeof(struct Source_File));
fclose(in);
return src;
}
- struct Translation_Data* get_translation_data()
+ struct Translation_Data* get_translation_data(struct Map *types)
{
struct Translation_Data *ret;
ret=malloc(sizeof(struct Translation_Data));
ret->macros=malloc(sizeof(struct Map));
Map_Init(ret->macros);
- ret->types=malloc(sizeof(struct Map));
- Map_Init(ret->types);
+ ret->types=types;
ret->number_of_errors_when_last_checked=0;
{
FILE *in;
char *temp_name;
+ char is_directory=0;
struct Source_Name *name;
+ struct Source_File *file;
+
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)
+ in=fopen(temp_name,"r");
+ free(temp_name);
+ if(in==NULL)
+ continue;
+
+ name=get_source_name(filename,*where_to_search);
+ file=extract_source_file(in,name);
+ if(file!=NULL)
+ {
+ return file;
+ }else
{
- free(temp_name);
- name=get_source_name(filename,*where_to_search);
- return extract_source_file(in,name);
+ delete_source_name(name);
}
- free(temp_name);
}while(*(++where_to_search));
return NULL;
}
}
program=get_program();
- hold_translation_data=get_translation_data();
+ hold_translation_data=get_translation_data(program->types);
do
{
base_file=get_source_file(*base_source_names,this_directory);
if(base_file==NULL)
{
/*TODO error*/
+ free(base_file);
continue;
}else
{
Queue_Push(hold_translation_data->source_files,base_file);
lex(base_file,hold_translation_data);
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);
+ assimilate_translation_data(program,hold_translation_data);
}
}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);
-
+ delete_translation_data(hold_translation_data);
return program;
}
char has_new_errors(struct Translation_Data *translation_data)
{
- if(translation_data->errors->size<translation_data->number_of_errors_when_last_checked)
+ if(translation_data->errors->size != translation_data->number_of_errors_when_last_checked)
{
translation_data->number_of_errors_when_last_checked=translation_data->errors->size;
return 1;
return 0;
}
}
+
+ void delete_program(struct Program *program)
+ {
+ while(program->translation_units->size>0)
+ delete_ast(Queue_Pop(program->translation_units));
+ free(program->translation_units);
+
+
+
+ while(program->source_files->size>0)
+ delete_source_file(Queue_Pop(program->source_files));
+ free(program->source_files);
+
+
+
+ while(program->errors->size>0)
+ delete_translation_error(Queue_Pop(program->errors));
+ delete_scope(program->externs);
+
+ /*BEWARE*/
+ Map_Map(program->types,free);
+ Map_Destroy(program->types);
+ free(program->types);
+
+ free(program);
+
+ }
+ void delete_translation_data(struct Translation_Data *translation_data)
+ {
+ assert(translation_data->tokens->size==0 &&
+ translation_data->errors->size==0 &&
+ translation_data->source_files->size==0);
+ free(translation_data->tokens);
+ free(translation_data->errors);
+ free(translation_data->source_files);
+
+ Map_Map(translation_data->macros,delete_macro);
+ Map_Destroy(translation_data->macros);
+ free(translation_data->macros);
+
+ }
+ void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data)
+ {
+ Queue_Append(program->errors,translation_data->errors);
+ Queue_Append(program->source_files,translation_data->source_files);
+
+ while(translation_data->tokens->size!=0)
+ {
+ free(Queue_Pop(translation_data->tokens));
+ }
+
+ Queue_Init(translation_data->errors);
+ Queue_Init(translation_data->source_files);
+
+ translation_data->number_of_errors_when_last_checked=0;
+
+
+ }
#endif
F diff --git a/semantics/program.h b/semantics/program.h
--- a/semantics/program.h
+++ b/semantics/program.h
struct Queue *source_files;
struct Queue *errors;
struct Scope *externs;
+
+ /*
+ we the type node structures from
+ all the translation units are stored here
+ */
+ struct Map *types;
};
struct Translation_Data
{
struct Map *macros;
+ /*passed from program struct*/
struct Map *types;
};
struct Source_File* get_source_file(char *filename,char **where_to_search);
void normalise_source_name(struct Source_Name *name);
- struct Translation_Data* get_translation_data();
+ struct Translation_Data* get_translation_data(struct Map *types);
struct Program* parse_program(char **base_source_names);
char has_new_errors(struct Translation_Data *translation_data);
+ void delete_program(struct Program *program);
+ void delete_translation_data(struct Translation_Data *translation_data);
+ void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data);
+
#endif
F diff --git a/semantics/scope.c b/semantics/scope.c
--- a/semantics/scope.c
+++ b/semantics/scope.c
void delete_normal_scope(struct Normal_Scope *scope)
{
-
+ Map_Map(&scope->tags,delete_denoted_wrapper);
+ Map_Destroy(&scope->tags);
+ Map_Map(&scope->ordinary,delete_denoted_wrapper);
+ Map_Destroy(&scope->ordinary);
+ free(scope);
}
void delete_function_scope(struct Function_Scope *scope)
{
-
+ Map_Map(&scope->labels,delete_denoted_wrapper);
+ Map_Destroy(&scope->labels);
+ free(scope);
}
void delete_scope(struct Scope *scope)
{
/*TODO fix this shit*/
assert(current->type!=FUNCTION_SCOPE);
-
+ assert(denot!=NULL);
Map_Push(&((struct Normal_Scope*)current)->tags,id->data,id->data_size,denot);
}
void push_ordinary(struct Scope *current,struct token *id,struct Denoted *denot)
{
assert(current->type!=FUNCTION_SCOPE);
+ assert(denot!=NULL);
Map_Push(&((struct Normal_Scope*)current)->ordinary,id->data,id->data_size,denot);
}
#endif
F diff --git a/semantics/type.c b/semantics/type.c
--- a/semantics/type.c
+++ b/semantics/type.c
#include "type.h"
- void type_check_and_push_heavy(struct Type_Map_Pair *pair,struct Type *type)
- {
- switch(type->specifier)
- {
- case TS_VOID:
- case TS_CHAR:
- case TS_INT:
- case TS_FLOAT:
- case TS_DOUBLE:
- type_check_and_push(pair,type,sizeof(struct Type_Basic));
- break;
- case TS_STRUCT:
- case TS_UNION:
- type_check_and_push(pair,type,sizeof(struct Type_Struct_Union));
- break;
- case TS_ENUM:
- type_check_and_push(pair,type,sizeof(struct Type_Enum));
- break;
- case TS_POINTER:
- type_check_and_push(pair,type,sizeof(struct Type_Pointer));
- break;
- case TS_ARRAY:
- type_check_and_push(pair,type,sizeof(struct Type_Array));
- break;
- case TS_FUNC:
- type_check_and_push(pair,type,sizeof(struct Type_Function));
- break;
- case TS_BITFIELD:
- type_check_and_push(pair,type,sizeof(struct Type_Bit_Field));
- break;
- case TS_ERROR:
- type_check_and_push(pair,type,sizeof(struct Type_Error));
- break;
- case TS_NONE:
- default:
- assert(0);
- }
- }
- void type_check_and_push(struct Type_Map_Pair *pair,struct Type *type,size_t struct_size)
+ struct Type* type_check_and_push(struct Type *type,struct Map *base,size_t struct_size)
{
-
struct Map *hold_node;
- hold_node=Map_Check_And_Get(pair->node,type,struct_size);
+ hold_node=Map_Check_And_Get(base,type,struct_size);
if(hold_node==NULL)
{
- pair->type=type;
- pair->node=Map_Push_And_Get(pair->node,type,struct_size,pair->type);
+ type->node=Map_Push_And_Get(base,type,struct_size,type);
+ return type;
}else
{
free(type);
- pair->node=hold_node;
- pair->type=(struct Type*)hold_node->ID;
+ return (struct Type*)hold_node->ID;
}
}
- void get_type_error(struct Type_Map_Pair *pair)
+ struct Type* get_type_error(struct Type *type)
{
struct Type_Error *ret;
- ret=malloc(sizeof(struct Type_Error));
+ ret=calloc(1,sizeof(struct Type_Error));
ret->specifier=TS_ERROR;
- ret->error=pair->type;
-
- type_check_and_push(pair,(struct Type*)ret,sizeof(struct Type_Error));
+ ret->error=type;
+ ret=(struct Type_Error*)type_check_and_push((struct Type*)ret,type->node,sizeof(struct Type_Error));
+ return (struct Type*)ret;
}
- void get_struct_union_type(struct Denotation_Prototype *prototype)
+ struct Type* get_struct_union_type(struct Denotation_Prototype *prototype)
{
struct Type_Struct_Union *ret;
assert(prototype->denotation=DT_Prototype);
prototype->denotation=DT_Object;
- ret=malloc(sizeof(struct Type_Struct_Union));
+ ret=calloc(1,sizeof(struct Type_Struct_Union));
ret->specifier=prototype->specifier;
ret->struct_union=prototype->struct_union;
ret->is_const=prototype->is_const;
ret->is_volatile=prototype->is_volatile;
- type_check_and_push(prototype->pair,(struct Type*)ret,sizeof(struct Type_Struct_Union));
+ ret=(struct Type_Struct_Union*)type_check_and_push((struct Type*)ret,prototype->node,sizeof(struct Type_Struct_Union));
if(prototype->constraint!=TC_NONE || prototype->sign!=TSIGN_NONE || (prototype->specifier!=TS_UNION && prototype->specifier!=TS_STRUCT))
{
- get_type_error(prototype->pair);
+ return get_type_error((struct Type*)ret);
+ }else
+ {
+ return (struct Type*)ret;
}
}
struct Struct_Union* get_struct_union_base(struct Scope *scope ,enum Type_Specifier struct_or_union)
struct Struct_Union *ret;
- ret=malloc(sizeof(struct Struct_Union));
+ ret=calloc(1,sizeof(struct Struct_Union));
ret->specifier=struct_or_union;
ret->members=malloc(sizeof(struct Queue));
Queue_Init(ret->members);
return ret;
}
- void get_basic_type(struct Denotation_Prototype *prototype)
+ struct Type* get_basic_type(struct Denotation_Prototype *prototype)
{
struct Type_Basic *ret;
- ret=malloc(sizeof(struct Type_Basic));
+ ret=calloc(1,sizeof(struct Type_Basic));
assert(prototype->denotation=DT_Prototype);
ret->is_const=prototype->is_const;
ret->is_volatile=prototype->is_volatile;
ret->constraint=prototype->constraint;
- ret->size=prototype->sign;
+ ret->sign=prototype->sign;
if(prototype->specifier==TS_NONE)
}
- type_check_and_push(prototype->pair,(struct Type*)ret,sizeof(struct Type_Basic));
+ ret=(struct Type_Basic*)type_check_and_push((struct Type*)ret,prototype->node,sizeof(struct Type_Basic));
- switch(prototype->pair->type->specifier)
+ switch(ret->specifier)
{
case TS_DOUBLE:
- if(prototype->constraint==TC_LONG_LONG
+ if(ret->constraint==TC_LONG_LONG
|| prototype->constraint==TC_SHORT
|| prototype->sign!=TSIGN_NONE)
{
- get_type_error(prototype->pair);
+ return get_type_error((struct Type*)ret);
}
break;
case TS_CHAR:
if(prototype->constraint!=TC_NONE)
{
- get_type_error(prototype->pair);
+ return get_type_error((struct Type*)ret);
}
break;
case TS_INT:
default:
if(prototype->constraint!=TC_NONE || prototype->sign!=TSIGN_NONE)
{
- get_type_error(prototype->pair);
+ return get_type_error((struct Type*)ret);
}
}
+ return (struct Type*)ret;
}
- void get_pointer_type(struct Type_Map_Pair *pair,char is_volatile,char is_constant)
+ struct Type* get_pointer_type(struct Type *points_to)
{
struct Type_Pointer *ret;
- ret=malloc(sizeof(struct Type_Pointer));
+ ret=calloc(1,sizeof(struct Type_Pointer));
ret->specifier=TS_POINTER;
ret->size=PTR_SIZE;
- ret->points_to=pair->type;
- ret->is_const=is_constant;
- ret->is_volatile=is_volatile;
+ ret->points_to=points_to;
+ ret->is_const=0;
+ ret->is_volatile=0;
- type_check_and_push(pair,(struct Type*)ret,sizeof(struct Type_Pointer));
+ ret=(struct Type_Pointer*)type_check_and_push((struct Type*)ret,points_to->node,sizeof(struct Type_Pointer));
+ return (struct Type*)ret;
}
- void get_array_type(struct Type_Map_Pair *pair,struct AST* number_of_elements)
+ struct Type* get_array_type(struct Type *array_of,struct AST* number_of_elements)
{
struct Type_Array *ret;
- ret=malloc(sizeof(struct Type_Array));
+ ret=calloc(1,sizeof(struct Type_Array));
ret->specifier=TS_ARRAY;
ret->size=0;
if(number_of_elements!=NULL)
{
ret->number_of_elements=0;
}
- ret->is_array_of=pair->type;
- type_check_and_push(pair,(struct Type*)ret,sizeof(struct Type_Array));
+ ret->is_array_of=array_of;
+ ret=(struct Type_Array*)type_check_and_push((struct Type*)ret,array_of->node,sizeof(struct Type_Array));
+ return (struct Type*)ret;
+
}
- void get_enum_type(struct Denotation_Prototype *prototype)
+ struct Type* get_enum_type(struct Denotation_Prototype *prototype)
{
struct Type_Enum *ret;
assert(prototype->denotation=DT_Prototype);
prototype->denotation=DT_Object;
- ret=malloc(sizeof(struct Type_Enum));
+ ret=calloc(1,sizeof(struct Type_Enum));
ret->specifier=TS_ENUM;
ret->enumeration=prototype->enumerator;
ret->is_const=prototype->is_const;
ret->is_volatile=prototype->is_volatile;
- type_check_and_push(prototype->pair,(struct Type*)ret,sizeof(struct Type_Enum));
+ ret=(struct Type_Enum*)type_check_and_push((struct Type*)ret,prototype->node,sizeof(struct Type_Enum));
if(prototype->sign!=TSIGN_NONE || prototype->constraint!=TC_NONE)
{
- get_type_error(prototype->pair);
+ return get_type_error((struct Type*)ret);
}
+ return (struct Type*)ret;
}
- void get_type_bitfield(struct Type_Map_Pair *pair,struct AST* number_of_bits)
+ struct Type* get_type_bitfield(struct Type *base,struct AST* number_of_bits)
{
struct Type_Bit_Field *ret;
- ret=malloc(sizeof(struct Type_Bit_Field));
+ ret=calloc(1,sizeof(struct Type_Bit_Field));
ret->specifier=TS_BITFIELD;
assert(number_of_bits!=NULL);
ret->number_of_bits=evaluate_const_expression_integer(number_of_bits);
delete_ast(number_of_bits);
- ret->base=pair->type;
+ ret->base=base;
- type_check_and_push(pair,(struct Type*)ret,sizeof(struct Type_Bit_Field));
+ ret=(struct Type_Bit_Field*)type_check_and_push((struct Type*)ret,base->node,sizeof(struct Type_Bit_Field));
+ return (struct Type*)ret;
}
- void get_function_type(struct Type_Map_Pair *pair,struct Queue *parameters,struct Normal_Scope* function_prototype_scope)
+ struct Type* get_function_type(struct Type *return_type,struct Queue *parameters,struct Normal_Scope* function_prototype_scope)
{
struct Type_Function *ret;
size_t i;
struct Map *hold_node;
- ret=malloc(sizeof(struct Type_Function));
+ ret=calloc(1,sizeof(struct Type_Function));
ret->specifier=TS_FUNC;
- ret->return_type=pair->type;
+ ret->return_type=return_type;
ret->function_prototype_scope=function_prototype_scope;
{
ret->arguments[i]=(struct Type*)Queue_Pop(parameters);
}
- type_check_and_push(pair,(struct Type*)ret,sizeof(struct Type_Function));
+ ret=(struct Type_Function*)type_check_and_push((struct Type*)ret,return_type->node,sizeof(struct Type_Function));
}
char is_type(struct Translation_Data *translation_data,struct Scope *scope)
}
}
- struct Type_Map_Pair* get_type_map_pair(struct Type *type,struct Map *types)
- {
- struct Type_Map_Pair *ret;
- ret=malloc(sizeof(struct Type_Map_Pair));
- ret->type=type;
- ret->node=types;
-
- return ret;
- }
void delete_enum(struct Enum *enumeration)
{
F diff --git a/semantics/type.h b/semantics/type.h
--- a/semantics/type.h
+++ b/semantics/type.h
struct Type
{
enum Type_Specifier specifier;
+ struct Map *node;
};
struct Type_Error
{
enum Type_Specifier specifier;
+ struct Map *node;
struct Type *error;
};
struct Type_Struct_Union
{
enum Type_Specifier specifier;
+ struct Map *node;
struct Struct_Union *struct_union;
char is_const:1;
struct Struct_Union
{
enum Type_Specifier specifier;
+ struct Map *node;
size_t size;
/*queue of denoted objects for preserving the order of the members*/
struct Queue *members;
struct Type_Bit_Field
{
enum Type_Specifier specifier;
+ struct Map *node;
size_t number_of_bits;
struct Type *base;
};
{
enum Type_Specifier specifier;
enum Type_Constraint constraint;
+ struct Map *node;
enum Type_Signedness sign;
size_t size;
char is_const:1;
char is_volatile:1;
- char is_signed:1;
};
struct Type_Pointer
{
enum Type_Specifier specifier;
+ struct Map *node;
size_t size;
struct Type *points_to;
char is_const:1;
struct Type_Array
{
enum Type_Specifier specifier;
+ struct Map *node;
size_t size;
size_t number_of_elements;
struct Type *is_array_of;
struct Type_Function
{
enum Type_Specifier specifier;
+ struct Map *node;
struct Type *return_type;
/*types*/
size_t number_of_arguments;
struct Type_Enum
{
enum Type_Specifier specifier;
+ struct Map *node;
struct Enum *enumeration;
char is_const:1;
char is_finished;
};
- struct Type_Map_Pair
- {
- struct Type *type;
- /*corresponding map node*/
- struct Map *node;
- };
+ struct Type* type_check_and_push(struct Type *type,struct Map *base,size_t struct_size);
- void type_check_and_push_heavy(struct Type_Map_Pair *pair,struct Type *type);
- void type_check_and_push(struct Type_Map_Pair *pair,struct Type *type,size_t struct_size);
- struct Type_Map_Pair* get_type_map_pair(struct Type *type,struct Map *types);
- void get_type_error(struct Type_Map_Pair *pair);
- void get_struct_union_type(struct Denotation_Prototype *prototype);
+ struct Type* get_type_error(struct Type *type);
+ struct Type* get_struct_union_type(struct Denotation_Prototype *prototype);
struct Struct_Union* get_struct_union_base(struct Scope *scope ,enum Type_Specifier struct_or_union);
struct Enum *get_enum_base();
- void get_basic_type(struct Denotation_Prototype *prototype);
- void get_pointer_type(struct Type_Map_Pair *pair,char is_volatile,char is_constant);
- void get_array_type(struct Type_Map_Pair *pair,struct AST* number_of_elements);
- void get_enum_type(struct Denotation_Prototype *prototype);
- void get_type_bitfield(struct Type_Map_Pair *pair,struct AST* number_of_bits);
+ struct Type* get_basic_type(struct Denotation_Prototype *prototype);
+ struct Type* get_pointer_type(struct Type *points_to);
+ struct Type* get_array_type(struct Type *array_of,struct AST* number_of_elements);
+ struct 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 Normal_Scope* function_prototype_scope);
void delete_enum(struct Enum *enumeration);
void delete_struct_union(struct Struct_Union *su);
- void get_function_type(struct Type_Map_Pair *pair,struct Queue *parameters,struct Normal_Scope* function_prototype_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
/*asdf*/#include/*asdf*/"test2.c"
- List main(int argc, char *argv[])
+ #define max(x,y) (x>y?x:y)
+
+
+ struct asdf
{
- long int c;
- int a,b[111+1];
- return 0;
+ List kek;
+ }a;
+ int main(int argc, char *argv[])
+ {
+ int fw;
+ int fx;
+ int fy;
+ int fz;
+ int ga;
+ int gb;
+ int gc;
+ int gd;
+ int ge;
+ int gf;
+ int gg;
+ int gh;
+ int gi;
+ int gj;
+ int gk;
+ int gl;
+ int gm;
+ int gn;
+ int go;
+ int gp;
+ int gq;
+ int gr;
+ int gs;
+ int gt;
+ int gu;
+ int gv;
+ int gw;
+ int gx;
+ int gy;
+ int gz;
+ int ha;
+ int hb;
+ int hc;
+ int hd;
+ int he;
+ int hf;
+ int hg;
+ int hh;
+ int hi;
+ int hj;
+ int hk;
+ int hl;
+ int hm;
+ int hn;
+ int ho;
+ int hp;
+ int hq;
+ int hr;
+ int hs;
+ int ht;
+ int hu;
+ int hv;
+ int hw;
+ int hx;
+ int hy;
+ int hz;
+ int ia;
+ int ib;
+ int ic;
+ int id;
+ int ie;
+ int ig;
+ int ih;
+ int ii;
+ int ij;
+ int ik;
+ int il;
+ int im;
+ int in;
+ int io;
+ int ip;
+ int iq;
+ int ir;
+ int is;
+ int it;
+ int iu;
+ int iv;
+ int iw;
+ int ix;
+ int iy;
+ int iz;
+ int ja;
+ int jb;
+ int jc;
+ int jd;
+ int je;
+ int jf;
+ int jg;
+ int jh;
+ int ji;
+ int jj;
+ int jk;
+ int jl;
+ int jm;
+ int jn;
+ int jo;
+ int jp;
+ int jq;
+ int jr;
+ int js;
+ int jt;
+ int ju;
+ int jv;
+ int jw;
+ int jx;
+ int jy;
+ int jz;
+ int ka;
+ int kb;
+ int kc;
+ int kd;
+ int ke;
+ int kf;
+ int kg;
+ int kh;
+ int ki;
+ int kj;
+ int kk;
+ int kl;
+ int km;
+ int kn;
+ int ko;
+ int kp;
+ int kq;
+ int kr;
+ int ks;
+ int kt;
+ int ku;
+ int kv;
+ int kw;
+ int kx;
+ int ky;
+ int kz;
+ int la;
+ int lb;
+ int lc;
+ int ld;
+ int le;
+ int lf;
+ int lg;
+ int lh;
+ int li;
+ int lj;
+ int lk;
+ int ll;
+ int lm;
+ int ln;
+ int lo;
+ int lp;
+ int lq;
+ int lr;
+ int ls;
+ int lt;
+ int lu;
+ int lv;
+ int lw;
+ int lx;
+ int ly;
+ int lz;
+ int ma;
+ int mb;
+ int mc;
+ int md;
+ int me;
+ int mf;
+ int mg;
+ int mh;
+ int mi;
+ int mj;
+ int mk;
+ int ml;
+ int mm;
+ int mn;
+ int mo;
+ int mp;
+ int mq;
+ int mr;
+ int ms;
+ int mt;
+ int mu;
+ int mv;
+ int mw;
+ int mx;
+ int my;
+ int mz;
+ int na;
+ int nb;
+ int nc;
+ int nd;
+ int ne;
+ int nf;
+ int ng;
+ int nh;
+ int ni;
+ int nj;
+ int nk;
+ int nl;
+ int nm;
+ int nn;
+ int no;
+ int np;
+ int nq;
+ int nr;
+ int ns;
+ int nt;
+ int nu;
+ int nv;
+ int nw;
+ int nx;
+ int ny;
+ int nz;
+ int oa;
+ int ob;
+ int oc;
+ int od;
+ int oe;
+ int of;
+ int og;
+ int oh;
+ int oi;
+ int oj;
+ int ok;
+ int ol;
+ int om;
+ int on;
+ int oo;
+ int op;
+ int oq;
+ int or;
+ int os;
+ int ot;
+ int ou;
+ int ov;
+ int ow;
+ int ox;
+ int oy;
+ int oz;
+ int pa;
+ int pb;
+ int pc;
+ int pd;
+ int pe;
+ int pf;
+ int pg;
+ int ph;
+ int pi;
+ int pj;
+ int pk;
+ int pl;
+ int pm;
+ int pn;
+ int po;
+ int pp;
+ int pq;
+ int pr;
+ int ps;
+ int pt;
+ int pu;
+ int pv;
+ int pw;
+ int px;
+ int py;
+ int pz;
+ int qa;
+ int qb;
+ int qc;
+ int qd;
+ int qe;
+ int qf;
+ int qg;
+ int qh;
+ int qi;
+ int qj;
+ int qk;
+ int ql;
+ int qm;
+ int qn;
+ int qo;
+ int qp;
+ int qq;
+ int qr;
+ int qs;
+ int qt;
+ int qu;
+ int qv;
+ int qw;
+ int qx;
+ int qy;
+ int qz;
+ int ra;
+ int rb;
+ int rc;
+ int rd;
+ int re;
+ int rf;
+ int rg;
+ int rh;
+ int ri;
+ int rj;
+ int rk;
+ int rl;
+ int rm;
+ int rn;
+ int ro;
+ int rp;
+ int rq;
+ int rr;
+ int rs;
+ int rt;
+ int ru;
+ int rv;
+ int rw;
+ int rx;
+ int ry;
+ int rz;
+ int sa;
+ int sb;
+ int sc;
+ int sd;
+ int se;
+ int sf;
+ int sg;
+ int sh;
+ int si;
+ int sj;
+ int sk;
+ int sl;
+ int sm;
+ int sn;
+ int so;
+ int sp;
+ int sq;
+ int sr;
+ int ss;
+ int st;
+ int su;
+ int sv;
+ int sw;
+ int sx;
+ int sy;
+ int sz;
+ int ta;
+ int tb;
+ int tc;
+ int td;
+ int te;
+ int tf;
+ int tg;
+ int th;
+ int ti;
+ int tj;
+ int tk;
+ int tl;
+ int tm;
+ int tn;
+ int to;
+ int tp;
+ int tq;
+ int tr;
+ int ts;
+ int tt;
+ int tu;
+ int tv;
+ int tw;
+ int tx;
+ int ty;
+ int tz;
+ int ua;
+ int ub;
+ int uc;
+ int ud;
+ int ue;
+ int uf;
+ int ug;
+ int uh;
+ int ui;
+ int uj;
+ int uk;
+ int ul;
+ int um;
+ int un;
+ int uo;
+ int up;
+ int uq;
+ int ur;
+ int us;
+ int ut;
+ int uu;
+ int uv;
+ int uw;
+ int ux;
+ int uy;
+ int uz;
+ int va;
+ int vb;
+ int vc;
+ int vd;
+ int ve;
+ int vf;
+ int vg;
+ int vh;
+ int vi;
+ int vj;
+ int vk;
+ int vl;
+ int vm;
+ int vn;
+ int vo;
+ int vp;
+ int vq;
+ int vr;
+ int vs;
+ int vt;
+ int vu;
+ int vv;
+ int vw;
+ int vx;
+ int vy;
+ int vz;
+ int wa;
+ int wb;
+ int wc;
+ int wd;
+ int we;
+ int wf;
+ int wg;
+ int wh;
+ int wi;
+ int wj;
+ int wk;
+ int wl;
+ int wm;
+ int wn;
+ int wo;
+ int wp;
+ int wq;
+ int wr;
+ int ws;
+ int wt;
+ int wu;
+ int wv;
+ int ww;
+ int wx;
+ int wy;
+ int wz;
+ int xa;
+ int xb;
+ int xc;
+ int xd;
+ int xe;
+ int xf;
+ int xg;
+ int xh;
+ int xi;
+ int xj;
+ int xk;
+ int xl;
+ int xm;
+ int xn;
+ int xo;
+ int xp;
+ int xq;
+ int xr;
+ int xs;
+ int xt;
+ int xu;
+ int xv;
+ int xw;
+ int xx;
+ int xy;
+ int xz;
+ int ya;
+ int yb;
+ int yc;
+ int yd;
+ int ye;
+ int yf;
+ int yg;
+ int yh;
+ int yi;
+ int yj;
+ int yk;
+ int yl;
+ int ym;
+ int yn;
+ int yo;
+ int yp;
+ int yq;
+ int yr;
+ int ys;
+ int yt;
+ int yu;
+ int yv;
+ int yw;
+ int yx;
+ int yy;
+ int yz;
+ int za;
+ int zb;
+ int zc;
+ int zd;
+ int ze;
+ int zf;
+ int zg;
+ int zh;
+ int zi;
+ int zj;
+ int zk;
+ int zl;
+ int zm;
+ int zn;
+ int zo;
+ int zp;
+ int zq;
+ int zr;
+ int zs;
+ int zt;
+ int zu;
+ int zv;
+ int zw;
+ int zx;
+ int zy;
+ int zz=1;
}
F diff --git a/tests/test3.c b/tests/test3.c
--- a/tests/test3.c
+++ b/tests/test3.c
+ #ifndef VERSION
+ #define VERSION 1
+ int kak;
+ #else
+ int err;
+ #endif
- int a;
- int b;
+ #ifdef VERSION
+ char charimander;
+ #endif