F diff --git a/doc/todo.txt b/doc/todo.txt --- a/doc/todo.txt +++ b/doc/todo.txtCreate a custom allocation system.Implement the const expression evaluation stuffAdd asm compilation stuff.+ Finish implementing initialiser parsing+ Make multiple definitions check+ Make variadic functions and macrosF 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.cvoid 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.celse{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;}}#endifF 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.cfprintf(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.cwhile(!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);+ elseQueue_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.cif(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.cif(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.cstruct 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.hstruct 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);-#endifF 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.cstruct 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.creturn 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);}#endifF 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);#endifF 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);+ }#endifF 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);++#endifF 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.cret=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;elseret->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.cret->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)+ {++ }#endifF 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.hstruct 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);+#endifF 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.cret=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;+ }