F diff --git a/doc/todo.txt b/doc/todo.txt
--- a/doc/todo.txt
+++ b/doc/todo.txt
Create a custom allocation system.
Implement the const expression evaluation stuff
Add asm compilation stuff.
+ Finish implementing initialiser parsing
+ Make multiple definitions check
+ Make variadic functions and macros
F diff --git a/src/backend/asm/intel/intel_compile.c b/src/backend/asm/intel/intel_compile.c
--- a/src/backend/asm/intel/intel_compile.c
+++ b/src/backend/asm/intel/intel_compile.c
void compile_translation_unit_to_intel_asm(struct Compile_Data_Intel_Asm *compile_data,struct AST_Translation_Unit *unit)
{
struct Queue_Node *it;
- for(it=unit->components->first;it!=NULL;it=it->prev)
+ for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
compile_ast_to_intel_asm(compile_data,it->data);
}
void compile_expression_statement(struct Compile_Data_Intel_Asm *compile_data,struct AST_Expression *expression)
F diff --git a/src/backend/text/print/print.c b/src/backend/text/print/print.c
--- a/src/backend/text/print/print.c
+++ b/src/backend/text/print/print.c
{
struct Queue_Node *it;
struct AST* hold;
- for(it=unit->components->first;it!=NULL;it=it->prev)
+ for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
{
hold=(struct AST*)(it->data);
print_ast(compile_data,(struct AST*)hold);
F diff --git a/src/debug/debug_ast.c b/src/debug/debug_ast.c
--- a/src/debug/debug_ast.c
+++ b/src/debug/debug_ast.c
else
{
struct Queue_Node *it;
- for(it=unit->components->first;it!=NULL;it=it->prev)
+ for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
if(!is_valid_ast(it->data))
return 0;
+ for(it=unit->static_objects->first;it!=NULL;it=it->prev)
+ if(!is_valid_ast(it->data))
+ return 0;
+
if(!is_valid_scope(unit->file_scope))
return 0;
if(!is_valid_linkage(unit->internal_linkage))
return 0;
- return unit->static_declarations!=NULL;
+ return 1;
}
}
#endif
F diff --git a/src/debug/debug_initialiser.c b/src/debug/debug_initialiser.c
--- a/src/debug/debug_initialiser.c
+++ b/src/debug/debug_initialiser.c
}
_Bool is_valid_initialiser(struct Initialiser *initialiser)
{
- return initialiser!=NULL && is_valid_initialiser_enum(initialiser->kind);
+ return initialiser==NULL || is_valid_initialiser_enum(initialiser->kind);
}
_Bool is_valid_initialiser_denoted(struct Initialiser_Denoted *initialiser)
F diff --git a/src/debug/wobler/wobler.c b/src/debug/wobler/wobler.c
--- a/src/debug/wobler/wobler.c
+++ b/src/debug/wobler/wobler.c
fprintf(stdout," -- %s",error_message);
}
+ if(test_times[current_test] <= tests[current_test].how_much_time_should_execution_take)
+ {
+ fprintf(wobler_log,"took %f seconds ",test_times[current_test]);
+ }
if(program)
dump_program(wobler_log,program);
F diff --git a/src/debug/wobler/wobler_tests.h b/src/debug/wobler/wobler_tests.h
--- a/src/debug/wobler/wobler_tests.h
+++ b/src/debug/wobler/wobler_tests.h
#ifndef WOBLER_TESTS_H
#define WOBLER_TESTS_H WOBLER_TESTS_H
+ #define TEST_TIME_BASELINE 1.0
+
struct test_entry
{
char *filenames[100];
{
.filenames={"test_generic.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_undeclared_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_preproc_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_declaration.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_declaration2.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_declaration_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_bitfields.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_generic_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_linkage.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_linkage2.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_linkage_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_linkage_error2.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_bitfield_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_bitfield_error2.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_bitfield_error3.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_function_definition_error.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_function_definition_error2.c"},
.test_function=should_not_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
{
.filenames={"test_function_definition.c"},
.test_function=should_compile,
- .how_much_time_should_execution_take=0.01,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
+ },
+ {
+ .filenames={"test_typedef.c"},
+ .test_function=should_compile,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
+ },
+ {
+ .filenames={"test_declaration_speed.c"},
+ .test_function=should_compile,
+ .how_much_time_should_execution_take=TEST_TIME_BASELINE,
},
};
F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c
--- a/src/frontend/parse/parse_declaration.c
+++ b/src/frontend/parse/parse_declaration.c
/*declaration-specifiers init-declarator (,init-declarator)* ;*/
/* init-declarator: declarator [ = initializer ] */
- void parse_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions)
+ void parse_declaration_inner(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push_objects,struct Queue *where_to_push_function_definitions,_Bool parse_function_definitions)
{
struct Denotation_Prototype *prototype;
struct Denoted *hold;
if(hold->denotation==DT_Function)
{
- Scope_Push(scope,hold,translation_data);
+ //Scope_Push(scope,hold,translation_data);
/*check if this is a function definition*/
if(parse_function_definitions && get_and_check(translation_data,KW_OPEN_CURLY))
{
- parse_finish_function_definition(translation_data,scope,(struct Denoted_Function*)hold,where_to_push);
+ parse_finish_function_definition(translation_data,scope,(struct Denoted_Function*)hold,where_to_push_function_definitions);
break; /*leave the declarator parser loop*/
- }else
- {
- /*this is a function declaration*/
- Queue_Push(where_to_push,get_function_declaration_tree(scope,(struct Denoted_Function*)hold));
}
- }else if(hold->denotation==DT_Typedef)
- {
- Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Type*)hold));
}else if(hold->denotation==DT_Object)
{
- parse_finish_object_declaration(translation_data,scope,(struct Denoted_Object*)hold,where_to_push);
+ parse_finish_object_declaration(translation_data,scope,(struct Denoted_Object*)hold,where_to_push_objects);
+ }else if(hold->denotation==DT_Typedef)
+ {
+ Scope_Push(scope,hold,translation_data);
}else
{
/*TODO error*/
- Queue_Push(where_to_push,get_declaration_error_tree(hold));
+ Queue_Push(where_to_push_objects,get_declaration_error_tree(hold));
push_translation_error("declaration expected",translation_data);
/*search for end of erronous declaration*/
wonky_assert(is_valid_denoted(hold));
- Scope_Push(scope,hold,translation_data);
- parse_function_definitions=0;
+ parse_function_definitions=0; /*here so we don't have int a,main(){ return 0 }*/
if(!get_and_check(translation_data,KW_COMMA) && !check(translation_data,KW_SEMI_COLUMN,0))
{
/*TODO error*/
- Queue_Push(where_to_push,get_declaration_error_tree(NULL));
+ Queue_Push(where_to_push_objects,get_declaration_error_tree(NULL));
push_translation_error("semi column expected",translation_data);
break;
}
}
+ void parse_external_definition(struct Translation_Data *translation_data,struct AST_Translation_Unit *unit)
+ {
+ parse_declaration_inner(translation_data,unit->file_scope,unit->static_objects,unit->function_definitions,1);
+ }
+ void parse_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push_declarations)
+ {
+ parse_declaration_inner(translation_data,scope,where_to_push_declarations,where_to_push_declarations,0);
+ }
void parse_finish_function_definition(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Function *function,struct Queue *where_to_push)
{
struct Type_Function *function_type;
struct AST_Compound_Statement *function_body;
+ struct AST_Function_Definition *function_definition;
function_type=(struct Type_Function*)function->type;
wonky_assert(is_valid_compound_statement(function_body));
- Queue_Push(where_to_push,get_function_definition_tree(scope,function,function_body,translation_data));
+ resolve_function_linkage(scope,translation_data,function);
+
+ Scope_Push(scope,(struct Denoted*)function,translation_data);
+
+ function_definition=get_function_definition_tree(scope,function,function_body,translation_data);
+
+ push_function_definition_into_linkage(translation_data,function_definition);
+ Queue_Push(where_to_push,function_definition);
}
void parse_finish_object_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *object,struct Queue *where_to_push)
{
struct Initialiser *initializer=NULL;
struct AST_Expression *to_be_initialised;
+ struct AST_Object_Declaration *object_declaration;
to_be_initialised=(struct AST_Expression*)get_designator_tree_from_denoted_object(object,translation_data);
if(get_and_check(translation_data,KW_EQ))
wonky_assert(is_valid_initialiser(initializer));
}
- Queue_Push(where_to_push,get_object_declaration_tree(object,initializer));
+
+ object_declaration=get_object_declaration_tree(object,initializer);
+
+ resolve_object_linkage(scope,translation_data,object);
+
+ Scope_Push(scope,(struct Denoted*)object,translation_data);
+
+ push_object_into_linkage(translation_data,object_declaration);
+
+ Queue_Push(where_to_push,object_declaration);
}
struct Denotation_Prototype* parse_specifier_qualifier_list(struct Translation_Data *translation_data,struct Scope *scope)
{
F diff --git a/src/frontend/parse/parse_declaration.h b/src/frontend/parse/parse_declaration.h
--- a/src/frontend/parse/parse_declaration.h
+++ b/src/frontend/parse/parse_declaration.h
- void parse_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions);
+ void parse_declaration_inner(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push_objects,struct Queue *where_to_push_function_definitions,_Bool parse_function_definitions);
+
+ void parse_external_definition(struct Translation_Data *translation_data,struct AST_Translation_Unit *unit);
+ void parse_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push_declarations);
+
+
+ void parse_external_declaration(struct Translation_Data *translation_data,struct AST_Translation_Unit *translation_unit);
void parse_finish_function_definition(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Function *function,struct Queue *where_to_push);
void parse_finish_object_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *object,struct Queue *where_to_push);
struct Denotation_Prototype* parse_specifier_qualifier_list(struct Translation_Data *translation_data,struct Scope *scope);
F diff --git a/src/frontend/parse/parse_statement.c b/src/frontend/parse/parse_statement.c
--- a/src/frontend/parse/parse_statement.c
+++ b/src/frontend/parse/parse_statement.c
while(!get_and_check(translation_data,KW_CLOSE_CURLY) && !has_no_tokens(translation_data))
{
if(is_type(translation_data,hold->scope,0))
- {
- parse_declaration(translation_data,hold->scope,&hold->components,0);
- }else
- {
+ parse_declaration(translation_data,hold->scope,&hold->components);
+ else
Queue_Push(&hold->components,parse_statement(translation_data,hold->scope,parse_data));
- }
+
if(has_new_errors(translation_data))
chase_next_semicolumn(translation_data);
}
F diff --git a/src/frontend/parse/parse_translation_unit.c b/src/frontend/parse/parse_translation_unit.c
--- a/src/frontend/parse/parse_translation_unit.c
+++ b/src/frontend/parse/parse_translation_unit.c
if(is_type(translation_data,hold->file_scope,0) || kw_get(translation_data)==KW_ID)
{
- parse_declaration(translation_data,hold->file_scope,hold->components,1);
+ parse_external_definition(translation_data,hold);
if(has_new_errors(translation_data))
{
chase_next_semicolumn(translation_data);
F diff --git a/src/misc/map.c b/src/misc/map.c
--- a/src/misc/map.c
+++ b/src/misc/map.c
if(temp == size)
{
- wonky_assert(tree->ID==NULL);
+ //wonky_assert(tree->ID==NULL);
tree->ID=id;
tree->is_final=1;
return;
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c
--- a/src/semantics/ast.c
+++ b/src/semantics/ast.c
struct Type_Function *id_type;
size_t i;
- id_type=(struct Type_Function*)extract_expresion_value_type(id->value,translation_data);
+ if(id->type==ERROR)
+ id_type=(struct Type_Function*)get_type_error(NULL);
+ else
+ id_type=(struct Type_Function*)extract_expresion_value_type(id->value,translation_data);
+
ret=malloc(sizeof(struct AST_Function_Expression));
ret->type=OP_FUNCTION;
ret->value=NULL; /*So, we need to know if there is some error somewhere before we can begin extracting lvalue information*/
ret=malloc(sizeof(struct AST_Translation_Unit));
ret->type=TRANSLATION_UNIT;
- ret->components=malloc(sizeof(struct Queue));
+ //ret->components=malloc(sizeof(struct Queue));
+
+ ret->static_objects=malloc(sizeof(struct Queue));
+ ret->function_definitions=malloc(sizeof(struct Queue));
+
ret->internal_linkage=get_linkage();
ret->file_scope=get_normal_scope(NULL,FILE_SCOPE);
- ret->static_declarations=malloc(sizeof(struct Queue));
-
-
-
- Queue_Init(ret->components);
- Queue_Init(ret->static_declarations);
+ Queue_Init(ret->static_objects);
+ Queue_Init(ret->function_definitions);
return ret;
}
}
void delete_ast_translation_unit(struct AST_Translation_Unit *translation_unit)
{
- while(translation_unit->components->size>0)
- delete_ast((struct AST*)Queue_Pop(translation_unit->components));
+ while(translation_unit->function_definitions->size>0)
+ delete_ast((struct AST*)Queue_Pop(translation_unit->function_definitions));
+ while(translation_unit->static_objects->size>0)
+ delete_ast((struct AST*)Queue_Pop(translation_unit->static_objects));
if(translation_unit->file_scope!=NULL)
delete_scope(translation_unit->file_scope);
delete_linkage(translation_unit->internal_linkage);
F diff --git a/src/semantics/ast.h b/src/semantics/ast.h
--- a/src/semantics/ast.h
+++ b/src/semantics/ast.h
struct AST_Translation_Unit
{
enum AST_Type type;
- struct Queue *components; /*Queue of external declarations*/
+ //struct Queue *components; /*Queue of external declarations*/
+
+ struct Queue *static_objects;
+ struct Queue *function_definitions;
struct Scope *file_scope;
struct Linkage *internal_linkage;
-
- struct Queue *static_declarations; /*Queue of declarations*/
};
void delete_ast_function_declaration(struct AST_Function_Declaration *function_declaration);
void delete_ast_translation_unit(struct AST_Translation_Unit *translation_unit);
-
#endif
F diff --git a/src/semantics/constraints/expression_constraints.c b/src/semantics/constraints/expression_constraints.c
--- a/src/semantics/constraints/expression_constraints.c
+++ b/src/semantics/constraints/expression_constraints.c
struct Type_Function *proposed_function_type;
size_t i;
- if(proposed_function->type==ERROR)
+ if(proposed_function->type==ERROR || proposed_function->id->type==ERROR)
return 0;
proposed_function_type=(struct Type_Function*)extract_expresion_value_type(proposed_function->id->value,translation_data);
F diff --git a/src/semantics/constraints/linkage_constraints.c b/src/semantics/constraints/linkage_constraints.c
--- a/src/semantics/constraints/linkage_constraints.c
+++ b/src/semantics/constraints/linkage_constraints.c
return 0;
}else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)
{
+ struct AST_Object_Declaration *hold_object;
linkage=(denoted_object->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
- hold_object=check_and_push_id(denoted_object,&linkage->ids,denoted_object->id);
+ hold_object=check_and_push_id(denoted_object,linkage->ids,denoted_object->id);
if(hold_object!=NULL)
{
- if(hold_object->denotation!=DT_Object)
+ if(hold_object->type!=ST_OBJECT_DECLARATION)
{
push_translation_error("linking an object to a function %D",translation_data,denoted_object);
push_translation_note("linking against %D",translation_data,hold_object);
return 0;
- }else if(!types_are_identical(hold_object->object->type,denoted_object->object->type))
+ }else if(!types_are_identical(hold_object->object->object->type,denoted_object->object->type))
{
push_translation_error("linking objects with mismatching types",translation_data);
push_translation_note("%t has type %T",translation_data,denoted_object->id,denoted_object->object->type);
- push_translation_note("whilst %t has type %T",translation_data,hold_object->id,hold_object->object->type);
+ push_translation_note("whilst %t has type %T",translation_data,hold_object->object->id,hold_object->object->object->type);
return 0;
+ }else
+ {
+ return 1;
}
}else
}else if(denoted_function->linkage==LINKAGE_EXTERNAL || denoted_function->linkage==LINKAGE_INTERNAL)
{
linkage=(denoted_function->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);
- hold_function=check_and_push_id(denoted_function,&linkage->ids,denoted_function->id);
+ hold_function=check_and_push_id(denoted_function,linkage->ids,denoted_function->id);
if(hold_function!=NULL)
{
{
push_translation_error("linking an function to a object",translation_data);
return 0;
- }
- if(!types_are_identical(hold_function->type,denoted_function->type))
+ }else if(!types_are_identical(hold_function->type,denoted_function->type))
{
push_translation_error("linking functions with mismatching types",translation_data);
return 0;
+ }else
+ {
+ return 1;
}
}else
{
{
wonky_assert(SHOULD_NOT_REACH_HERE);
}
+
+ wonky_assert(SHOULD_NOT_REACH_HERE);
}
#endif
F diff --git a/src/semantics/constraints/linkage_constraints.h b/src/semantics/constraints/linkage_constraints.h
--- a/src/semantics/constraints/linkage_constraints.h
+++ b/src/semantics/constraints/linkage_constraints.h
#include <scope.h>
#include <denoted.h>
#include <common.h>
+ #include <program.h>
+ #include <linkage.h>
+
_Bool constraint_check_object_linkage(struct Denoted_Object *denoted_object ,struct Denoted *previous_denoted_with_same_id, struct Scope *current,struct Translation_Data *translation_data);
_Bool constraint_check_function_linkage(struct Denoted_Function *denoted_function,struct Denoted *previous_denoted_with_same_id,struct Scope *current,struct Translation_Data *translation_data);
+
+ //_Bool constrain_check_for_multiple_initialisations_of_object(struct Program *program,struct Translation_Data *translation_data);
#endif
F diff --git a/src/semantics/identifiers/linkage.c b/src/semantics/identifiers/linkage.c
--- a/src/semantics/identifiers/linkage.c
+++ b/src/semantics/identifiers/linkage.c
#ifndef WONKY_LINKAGE_C
#define WONKY_LINKAGE_C WONKY_LINKAGE_C
- #include<linkage.h>
+ #include <linkage.h>
{
struct Linkage *ret;
ret=malloc(sizeof(struct Linkage));
- Map_Init(&ret->ids);
+ ret->ids=malloc(sizeof(struct Map));
+
+ Map_Init(ret->ids);
return ret;
}
/*denoted things are deleted here and left alone when deleting scopes*/
void delete_linkage(struct Linkage *linkage)
{
- Map_Map(&linkage->ids,delete_denoted_wrapper);
- Map_Destroy(&linkage->ids);
+ Map_Destroy(linkage->ids);
free(linkage);
}
if(hold_object->linkage!=LINKAGE_NONE)
{
denoted_object->linkage=hold_object->linkage;
- //denoted_object->object->storage_class=SCS_STATIC; //TODO remove these, storage class should be handled at object constructor
}else
{
denoted_object->linkage=LINKAGE_EXTERNAL;
- //denoted_object->object->storage_class=SCS_STATIC;
}
}else
{
denoted_object->linkage=LINKAGE_EXTERNAL;
- //denoted_object->object->storage_class=SCS_STATIC;
}
}
void account_for_upper_linkage_on_function(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function)
/*check if id is linked oppositely*/
if(denoted_object->linkage==LINKAGE_EXTERNAL &&
- Map_Check(&translation_data->internal_linkage->ids,denoted_object->id->data,denoted_object->id->data_size)!=NULL)
+ Map_Check(translation_data->internal_linkage->ids,denoted_object->id->data,denoted_object->id->data_size)!=NULL)
{
push_translation_error("linking id both internally and externally",translation_data);
}else if(denoted_object->linkage==LINKAGE_INTERNAL &&
- Map_Check(&translation_data->external_linkage->ids,denoted_object->id->data,denoted_object->id->data_size)!=NULL)
+ Map_Check(translation_data->external_linkage->ids,denoted_object->id->data,denoted_object->id->data_size)!=NULL)
{
push_translation_error("linking id both internally and externally",translation_data);
}
/*check if id is linked oppositely*/
if(denoted_function->linkage==LINKAGE_EXTERNAL &&
- Map_Check(&translation_data->internal_linkage->ids,denoted_function->id->data,denoted_function->id->data_size)!=NULL)
+ Map_Check(translation_data->internal_linkage->ids,denoted_function->id->data,denoted_function->id->data_size)!=NULL)
{
push_translation_error("linking id both internally and externally",translation_data);
}else if(denoted_function->linkage==LINKAGE_INTERNAL &&
- Map_Check(&translation_data->external_linkage->ids,denoted_function->id->data,denoted_function->id->data_size)!=NULL)
+ Map_Check(translation_data->external_linkage->ids,denoted_function->id->data,denoted_function->id->data_size)!=NULL)
{
push_translation_error("linking id both internally and externally",translation_data);
}
+ }
+ void push_object_into_linkage(struct Translation_Data *translation_data,struct AST_Object_Declaration *object)
+ {
+ wonky_assert(is_valid_ast((struct AST*)object));
+
+ if(object->object->linkage==LINKAGE_EXTERNAL)
+ Map_Push(translation_data->external_linkage->ids,object->object->id->data,object->object->id->data_size,object);
+ else if(object->object->linkage==LINKAGE_INTERNAL)
+ Map_Push(translation_data->internal_linkage->ids,object->object->id->data,object->object->id->data_size,object);
}
+ void push_function_into_linkage(struct Translation_Data *translation_data,struct AST *function)
+ {
+ wonky_assert(is_valid_ast(function) && function->type==ST_FUNCTION_DEFINITION || function->type==ST_FUNCTION_DECLARATION);
+ if(function->type==ST_FUNCTION_DECLARATION)
+ push_function_declaration_into_linkage(translation_data,(struct AST_Function_Declaration*)function);
+ else
+ push_function_definition_into_linkage(translation_data,(struct AST_Function_Definition*)function);
+ }
+ void push_function_definition_into_linkage(struct Translation_Data *translation_data,struct AST_Function_Definition *function)
+ {
+ if(function->function->linkage==LINKAGE_EXTERNAL)
+ Map_Push(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size,function);
+ else
+ Map_Push(translation_data->internal_linkage->ids,function->function->id->data,function->function->id->data_size,function);
+ }
+ void push_function_declaration_into_linkage(struct Translation_Data *translation_data,struct AST_Function_Declaration *function)
+ {
+ if(function->function->linkage==LINKAGE_EXTERNAL)
+ Map_Push(translation_data->external_linkage->ids,function->function->id->data,function->function->id->data_size,function);
+ else
+ Map_Push(translation_data->internal_linkage->ids,function->function->id->data,function->function->id->data_size,function);
+ }
#endif
F diff --git a/src/semantics/identifiers/linkage.h b/src/semantics/identifiers/linkage.h
--- a/src/semantics/identifiers/linkage.h
+++ b/src/semantics/identifiers/linkage.h
/*this can be external or internal depending on which structure it is located*/
struct Linkage
{
- struct Map ids;
+ /*
+ We push ASTs here ( object declarations and function declaration/definitions
+ The reason we push ASTs and not denoted objects is to check for reinitialisation
+ of objects or redefinition of functions
+ */
+ struct Map *ids;
};
struct Linkage* get_linkage();
void delete_linkage();
- /*these don't push the object into the linkage map*/
+ /*These do not push to the linkage maps. They change linkage depending on the conditions*/
void resolve_object_linkage(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object);
void resolve_function_linkage(struct Scope *scope,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function);
+
+ /*These push the declarations to the ids map*/
+ void push_object_into_linkage(struct Translation_Data *translation_data,struct AST_Object_Declaration *object);
+ void push_function_into_linkage(struct Translation_Data *translation_data,struct AST *function);
+
+ void push_function_definition_into_linkage(struct Translation_Data *translation_data,struct AST_Function_Definition *function);
+ void push_function_declaration_into_linkage(struct Translation_Data *translation_data,struct AST_Function_Declaration *function);
+
+
#endif
F diff --git a/src/semantics/identifiers/scope.c b/src/semantics/identifiers/scope.c
--- a/src/semantics/identifiers/scope.c
+++ b/src/semantics/identifiers/scope.c
- resolve_object_linkage(current,translation_data,denoted_object);
hold_previous=check_and_push_id(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary,denoted_object->id);
wonky_assert(current->type!=FUNCTION_SCOPE);
- resolve_function_linkage(current,translation_data,denoted_function);
hold_previous=check_and_push_id(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary,denoted_function->id);
F diff --git a/src/semantics/memory/object.c b/src/semantics/memory/object.c
--- a/src/semantics/memory/object.c
+++ b/src/semantics/memory/object.c
ret=malloc(sizeof(struct Object));
ret->kind=OBJECT_KIND_NORMAL;
ret->type=type;
+ ret->storage_class=storage_class;
+ /*
if(storage_class==SCS_EXTERN || storage_class==SCS_STATIC)
ret->storage_class=SCS_STATIC;
else if(storage_class==SCS_REGISTER)
ret->storage_class=storage_class;
else
ret->storage_class=SCS_NONE;
+ */
ret->location=NULL;
return ret;
F diff --git a/src/semantics/program/program.c b/src/semantics/program/program.c
--- a/src/semantics/program/program.c
+++ b/src/semantics/program/program.c
ret->source_files=malloc(sizeof(struct Queue));
ret->errors=malloc(sizeof(struct Queue));
ret->types=malloc(sizeof(struct Map));
+ ret->functions_without_a_definition=malloc(sizeof(struct Queue));
+ ret->external_objects_without_an_initialiser=malloc(sizeof(struct Queue));
+
+
ret->external_linkage=get_linkage();
Queue_Init(ret->translation_units);
Queue_Init(ret->source_files);
Queue_Init(ret->errors);
+ Queue_Init(ret->functions_without_a_definition);
+ Queue_Init(ret->external_objects_without_an_initialiser);
assimilate_translation_data(program,hold_translation_data);
}
}while(*(++base_source_names));
+
+ find_functions_without_definitions(program);
+ find_external_objects_without_an_initialiser(program);
delete_translation_data(hold_translation_data);
return program;
{
return (translation_data->tokens->size)==0;
}
+
+ /*TODO*/
+ void find_functions_without_definitions(struct Program *program)
+ {
+
+ }
+ /*TODO*/
+ void find_external_objects_without_an_initialiser(struct Program *program)
+ {
+
+ }
#endif
F diff --git a/src/semantics/program/program.h b/src/semantics/program/program.h
--- a/src/semantics/program/program.h
+++ b/src/semantics/program/program.h
struct Map *types;
struct Linkage *external_linkage;
+
+ struct Queue *functions_without_a_definition;
+ struct Queue *external_objects_without_an_initialiser;
};
struct Translation_Data
{
void destroy_translation_data(struct Translation_Data *translation_data);
void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data);
+ void find_functions_without_definitions(struct Program *program);
+ void find_external_objects_without_an_initialiser(struct Program *program);
+
#endif
F diff --git a/src/semantics/value/type.c b/src/semantics/value/type.c
--- a/src/semantics/value/type.c
+++ b/src/semantics/value/type.c
ret=calloc(1,sizeof(struct Type_Error));
ret->specifier=TS_ERROR;
ret->error=type;
- ret=(struct Type_Error*)type_check_and_push((struct Type*)ret,type->node,sizeof(struct Type_Error));
+ if(type!=NULL)
+ ret=(struct Type_Error*)type_check_and_push((struct Type*)ret,type->node,sizeof(struct Type_Error));
wonky_assert(is_valid_type_error(ret));
return (struct Type*)ret;
F diff --git a/tests/test_typedef.c b/tests/test_typedef.c
new file mode 100644
--- /dev/null
+++ b/tests/test_typedef.c
+
+
+ typedef double (*rfunc)(double);
+
+ double d_id(double x)
+ {
+ return x;
+ }
+
+
+ int main()
+ {
+ rfunc func;
+ func=d_id;
+ func(0);
+
+ return 0;
+ }