F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txtsrc/semantics/value/constant.csrc/semantics/constraints/expression_constraints.csrc/semantics/constraints/statement_constraints.c+ src/semantics/constraints/linkage_constraints.csrc/semantics/value/value.csrc/semantics/identifiers/denoted.csrc/semantics/identifiers/scope.cF diff --git a/src/backend/print/print.c b/src/backend/print/print.c --- a/src/backend/print/print.c +++ b/src/backend/print/print.cvoid print_token(FILE *out,struct token *token){size_t i;- // fprintf(out,"[");if(token==NULL)return;for(i=0;i<token->data_size;++i){fprintf(out,"%c",token->data[i]);}- // fprintf(out,"]");}char print_tokens_of_program(FILE *out,char **base_source_names){switch(op){- case OP_COMMA:- fprintf(out,",");break;- case OP_ADDITION:- fprintf(out,"+");break;- case OP_SUBTRACTION:- fprintf(out,"-");break;- case OP_MUL:- fprintf(out,"*");break;- case OP_DIV:- fprintf(out,"/");break;- case OP_REMAINDER:- fprintf(out,"%");break;- case OP_COND:- fprintf(out,"CONDITIONAL");break;- case OP_FUNCTION:- fprintf(out,"FUNCTION_CALL");break;- case OP_ASSIGN:- fprintf(out,"=");break;- case OP_ADD_ASSIGN:- fprintf(out,"+=");break;- case OP_SUBTRACT_ASSIGN:- fprintf(out,"-=");break;- case OP_MULTIPLY_ASSIGN:- fprintf(out,"*=");break;- case OP_REMAINDER_ASSIGN:- fprintf(out,"%=");break;- case OP_DIV_ASSIGN:- fprintf(out,"/=");break;- case OP_SHIFT_LEFT_ASSIGN:- fprintf(out,">>=");break;- case OP_SHIFT_RIGHT_ASSIGN:- fprintf(out,"<<=");break;- case OP_AND_ASSIGN:- fprintf(out,"&=");break;- case OP_XOR_ASSIGN:- fprintf(out,"^=");break;- case OP_PIPE_ASSIGN:- fprintf(out,"|=");break;- case OP_NOP:- fprintf(out,"NOP");break;- case OP_LOGICAL_OR:- fprintf(out,"||");break;- case OP_LOGICAL_AND:- fprintf(out,"&&");break;- case OP_LOGICAL_NOT:- fprintf(out,"!");break;- case OP_BITWISE_OR:- fprintf(out,"|");break;- case OP_BITWISE_AND:- fprintf(out,"&");break;- case OP_BITWISE_XOR:- fprintf(out,"^");break;- case OP_BITWISE_NOT:- fprintf(out,"~");break;- case OP_ADDR_OF:- fprintf(out,"&");break;- case OP_DEREFERENCE:- fprintf(out,"*");break;- case OP_MEMBER_TROUGH_PTR:- fprintf(out,"->");break;- case OP_MEMBER:- fprintf(out,".");break;- case OP_ARR_SUBSCRIPT:- fprintf(out,"ARR_SUBSCRIPT");break;- case OP_POSTFIX_INC:- fprintf(out,"++");break;- case OP_POSTFIX_DEC:- fprintf(out,"--");break;- case OP_PREFIX_INC:- fprintf(out,"++");break;- case OP_PREFIX_DEC:- fprintf(out,"--");break;- case OP_UNARY_PLUS:- fprintf(out,"+");break;- case OP_UNARY_MINUS:- fprintf(out,"-");break;- case OP_CAST:- fprintf(out,"CAST");break;- case OP_SIZEOF:- fprintf(out,"sizeof");break;- case OP_SHIFT_LEFT:- fprintf(out,"<<");break;- case OP_SHIFT_RIGHT:- fprintf(out,">>");break;- case OP_LESS_EQ:- fprintf(out,"<=");break;- case OP_GREATER_EQ:- fprintf(out,">=");break;- case OP_LESS:- fprintf(out,"<");break;- case OP_GREATER:- fprintf(out,">");break;- case OP_EQUAL:- fprintf(out,"==");break;- case OP_NOT_EQUAL:- fprintf(out,"!=");break;- case OP_CONSTANT:- fprintf(out,"CONSTANT");break;- case OP_STRING_LITERAL:- fprintf(out,"STRING_LITERAL");break;- case ST_COMPOUND:- fprintf(out,"COMPOUND");break;- case ST_EXPRESSION:- fprintf(out,"EXPRESSION");break;- case ST_SWITCH:- fprintf(out,"switch");break;- case ST_IF:- fprintf(out,"if");break;- case ST_WHILE:- fprintf(out,"while");break;- case ST_DO_WHILE:- fprintf(out,"do_while");break;- case ST_GOTO:- fprintf(out,"goto");break;- case ST_LABEL:- fprintf(out,"LABEL");break;- case ST_CASE:- fprintf(out,"case");break;- case ST_DEFAULT:- fprintf(out,"default");break;- case ST_CONTINUE:- fprintf(out,"continue");break;- case ST_BREAK:- fprintf(out,"break");break;- case ST_RETURN:- fprintf(out,"return");break;- case ST_FOR:- fprintf(out,"for");break;-- /*TODO obj dec obj def func decl*/- case ST_FUNCTION_DEFINITION:- fprintf(out,"FUNCTION_DEFINITION");break;- case TRANSLATION_UNIT:- fprintf(out,"TRANSLATION_UNIT");break;- case ERROR:- fprintf(out,"ERROR");break;- default:- fprintf(out,"NOT_POSSIBLE");break;+ case OP_COMMA:+ fprintf(out,",");break;+ case OP_ADDITION:+ fprintf(out,"+");break;+ case OP_SUBTRACTION:+ fprintf(out,"-");break;+ case OP_MUL:+ fprintf(out,"*");break;+ case OP_DIV:+ fprintf(out,"/");break;+ case OP_REMAINDER:+ fprintf(out,"%");break;+ case OP_COND:+ fprintf(out,"CONDITIONAL");break;+ case OP_FUNCTION:+ fprintf(out,"FUNCTION_CALL");break;+ case OP_ASSIGN:+ fprintf(out,"=");break;+ case OP_ADD_ASSIGN:+ fprintf(out,"+=");break;+ case OP_SUBTRACT_ASSIGN:+ fprintf(out,"-=");break;+ case OP_MULTIPLY_ASSIGN:+ fprintf(out,"*=");break;+ case OP_REMAINDER_ASSIGN:+ fprintf(out,"%=");break;+ case OP_DIV_ASSIGN:+ fprintf(out,"/=");break;+ case OP_SHIFT_LEFT_ASSIGN:+ fprintf(out,">>=");break;+ case OP_SHIFT_RIGHT_ASSIGN:+ fprintf(out,"<<=");break;+ case OP_AND_ASSIGN:+ fprintf(out,"&=");break;+ case OP_XOR_ASSIGN:+ fprintf(out,"^=");break;+ case OP_PIPE_ASSIGN:+ fprintf(out,"|=");break;+ case OP_NOP:+ fprintf(out,"NOP");break;+ case OP_LOGICAL_OR:+ fprintf(out,"||");break;+ case OP_LOGICAL_AND:+ fprintf(out,"&&");break;+ case OP_LOGICAL_NOT:+ fprintf(out,"!");break;+ case OP_BITWISE_OR:+ fprintf(out,"|");break;+ case OP_BITWISE_AND:+ fprintf(out,"&");break;+ case OP_BITWISE_XOR:+ fprintf(out,"^");break;+ case OP_BITWISE_NOT:+ fprintf(out,"~");break;+ case OP_ADDR_OF:+ fprintf(out,"&");break;+ case OP_DEREFERENCE:+ fprintf(out,"*");break;+ case OP_MEMBER_TROUGH_PTR:+ fprintf(out,"->");break;+ case OP_MEMBER:+ fprintf(out,".");break;+ case OP_ARR_SUBSCRIPT:+ fprintf(out,"ARR_SUBSCRIPT");break;+ case OP_POSTFIX_INC:+ fprintf(out,"++");break;+ case OP_POSTFIX_DEC:+ fprintf(out,"--");break;+ case OP_PREFIX_INC:+ fprintf(out,"++");break;+ case OP_PREFIX_DEC:+ fprintf(out,"--");break;+ case OP_UNARY_PLUS:+ fprintf(out,"+");break;+ case OP_UNARY_MINUS:+ fprintf(out,"-");break;+ case OP_CAST:+ fprintf(out,"CAST");break;+ case OP_SIZEOF:+ fprintf(out,"sizeof");break;+ case OP_SHIFT_LEFT:+ fprintf(out,"<<");break;+ case OP_SHIFT_RIGHT:+ fprintf(out,">>");break;+ case OP_LESS_EQ:+ fprintf(out,"<=");break;+ case OP_GREATER_EQ:+ fprintf(out,">=");break;+ case OP_LESS:+ fprintf(out,"<");break;+ case OP_GREATER:+ fprintf(out,">");break;+ case OP_EQUAL:+ fprintf(out,"==");break;+ case OP_NOT_EQUAL:+ fprintf(out,"!=");break;+ case OP_CONSTANT:+ fprintf(out,"CONSTANT");break;+ case OP_STRING_LITERAL:+ fprintf(out,"STRING_LITERAL");break;+ case ST_COMPOUND:+ fprintf(out,"COMPOUND");break;+ case ST_EXPRESSION:+ fprintf(out,"EXPRESSION");break;+ case ST_SWITCH:+ fprintf(out,"switch");break;+ case ST_IF:+ fprintf(out,"if");break;+ case ST_WHILE:+ fprintf(out,"while");break;+ case ST_DO_WHILE:+ fprintf(out,"do_while");break;+ case ST_GOTO:+ fprintf(out,"goto");break;+ case ST_LABEL:+ fprintf(out,"LABEL");break;+ case ST_CASE:+ fprintf(out,"case");break;+ case ST_DEFAULT:+ fprintf(out,"default");break;+ case ST_CONTINUE:+ fprintf(out,"continue");break;+ case ST_BREAK:+ fprintf(out,"break");break;+ case ST_RETURN:+ fprintf(out,"return");break;+ case ST_FOR:+ fprintf(out,"for");break;++ /*TODO obj dec obj def func decl*/+ case ST_FUNCTION_DEFINITION:+ fprintf(out,"FUNCTION_DEFINITION");break;+ case TRANSLATION_UNIT:+ fprintf(out,"TRANSLATION_UNIT");break;+ case ERROR:+ fprintf(out,"ERROR");break;+ default:+ fprintf(out,"NOT_POSSIBLE");break;}}void print_conditional_expression_tree(FILE *out,struct AST_Conditional_Expression *cond){fprintf(out,"(");- print_ast(out,(struct AST*)(struct AST*)cond->left);+ print_ast(out,(struct AST*)cond->left);fprintf(out,"?");- print_ast(out,(struct AST*)(struct AST*)cond->center);+ print_ast(out,(struct AST*)cond->center);fprintf(out,":");- print_ast(out,(struct AST*)(struct AST*)cond->right);+ print_ast(out,(struct AST*)cond->right);fprintf(out,")");}void print_function_expression_tree(FILE *out,struct AST_Function_Expression *function_call){struct Queue_Node *it;struct AST* hold;- for(it=unit->components.first;it!=NULL;it=it->prev)+ for(it=unit->components->first;it!=NULL;it=it->prev){hold=(struct AST*)(it->data);print_ast(out,(struct AST*)hold);break;case ST_OBJECT_DECLARATION:print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);- fprintf(out,"=");- print_ast(out,(struct AST*)((struct AST_Object_Declaration*)tree)->object->initializer);break;case ST_TYPE_DEFINITION:print_denoted(out,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);print_denoted(out,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);break;case ST_FUNCTION_DEFINITION:- print_function_definition(out,((struct AST_Function_Declaration*)tree)->function);+ print_function_definition(out,(struct AST_Function_Definition*)tree);break;case TRANSLATION_UNIT:print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree);}- void print_function_definition(FILE *out,struct Denoted_Function *function)+ void print_function_definition(FILE *out,struct AST_Function_Definition *function){- print_token(out,function->id);+ print_token(out,function->function->id);fprintf(out," is");- switch(function->linkage)+ switch(function->function->linkage){case LINKAGE_EXTERNAL:fprintf(out," an externally linked ");default:assert(0);}- print_type(out,function->type,1);- print_ast(out,(struct AST*)(struct AST*)function->body);+ print_type(out,function->function->type,1);+ print_compound_statement_tree(out,function->body);}void print_program_ast(FILE *out,struct Program *program){F diff --git a/src/backend/print/print.h b/src/backend/print/print.h --- a/src/backend/print/print.h +++ b/src/backend/print/print.hvoid print_program_tokens(FILE *out,struct Program *program);void print_program_ast(FILE *out,struct Program *program);void print_keyword_enum(FILE *out,enum KEYWORDS kw);- void print_function_definition(FILE *out,struct Denoted_Function *function);+ void print_function_definition(FILE *out,struct AST_Function_Definition *function);void print_errors(FILE *out,struct Queue *errors);void print_function_args(FILE *out,struct Type_Function *func);void print_type_qualifier(FILE *out,struct Type *type);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{struct Type_Function *function_type;struct Denoted_Function *hold_function;+ struct AST_Compound_Statement *function_body;hold_function=(struct Denoted_Function*)hold;function_type=(struct Type_Function*)((struct Denoted_Function*)hold)->type;function_type->function_prototype_scope->parent=(struct Scope*)hold_function->function_scope;- hold_function->body+ function_body=(struct AST_Compound_Statement*)parse_finish_compound_statement(});- Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold,translation_data));+ Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold,function_body,translation_data));break;}/*this is a function declaration*/Queue_Push(where_to_push,get_type_definition_tree((struct Denoted_Type*)hold));}else if(hold->denotation==DT_Object){- Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold));+ struct AST_Expression *initializer=NULL;if(get_and_check(translation_data,KW_EQ))- ((struct Denoted_Object*)hold)->initializer=parse_initializer(translation_data,scope,(struct Denoted_Object*)hold);+ initializer=(struct AST_Expression*)parse_initializer(translation_data,scope,(struct Denoted_Object*)hold);+ Queue_Push(where_to_push,get_object_declaration_tree((struct Denoted_Object*)hold,initializer));}else{/*TODO error*/F diff --git a/src/frontend/parse/parse_expression.c b/src/frontend/parse/parse_expression.c --- a/src/frontend/parse/parse_expression.c +++ b/src/frontend/parse/parse_expression.ccase KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:case KW_LONG_OCTAL_CONSTANT:case KW_LONG_LONG_OCTAL_CONSTANT:- assert(!"make octal constants");+ return (struct AST_Expression*)get_constant_tree(get_expression_value_constant(extract_literal_integer_octal(hold_token,translation_data)));case KW_DOUBLE_DECIMAL_CONSTANT:case KW_LONG_DOUBLE_DECIMAL_CONSTANT: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) || kw_get(translation_data)==KW_ID){- parse_declaration(translation_data,hold->file_scope,&hold->components,1);+ parse_declaration(translation_data,hold->file_scope,hold->components,1);if(has_new_errors(translation_data)){chase_next_semicolumn(translation_data);F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.creturn ret;}- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object)+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST_Expression *initialiser){struct AST_Object_Declaration *ret;ret=malloc(sizeof(struct AST_Object_Declaration));ret->type=ST_OBJECT_DECLARATION;ret->object=object;+ ret->initializer=initialiser;return ret;}- struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct Translation_Data *translation_data)+ struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct AST_Compound_Statement *function_body,struct Translation_Data *translation_data){struct AST_Function_Definition *ret;ret=malloc(sizeof(struct AST_Function_Definition));ret->type=ST_FUNCTION_DEFINITION;ret->function=function;+ ret->body=function_body;if(!constraint_check_function_definition(ret,translation_data))return (struct AST_Function_Definition*)get_error_tree((struct AST*)ret);{struct AST_Translation_Unit *ret;ret=malloc(sizeof(struct AST_Translation_Unit));+ ret->type=TRANSLATION_UNIT;+ ret->components=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_objects);- ret->type=TRANSLATION_UNIT;- return ret;- }+ Queue_Init(ret->components);+ Queue_Init(ret->static_declarations);- /*- * TODO- */- _Bool ast_is_a_constant_expression(struct AST *ast,struct Translation_Data *translation_data)- {- return 0;+ return ret;}void delete_ast(struct AST* ast)}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->components->size>0)+ delete_ast((struct AST*)Queue_Pop(translation_unit->components));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{enum AST_Type type;struct Denoted_Object *object;+ struct AST_Expression *initializer;};struct AST_Function_Definition{enum AST_Type type;struct Denoted_Function *function;+ struct AST_Compound_Statement *body;};struct AST_Function_Declaration{struct AST_Translation_Unit{enum AST_Type type;- struct Queue components;+ struct Queue *components; /*Queue of external declarations*/struct Scope *file_scope;struct Linkage *internal_linkage;- struct Queue static_objects;++ struct Queue *static_declarations; /*Queue of declarations*/};struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope,struct Translation_Data *translation_data);struct AST* get_nop_tree();struct AST_Type_Definition* get_type_definition_tree(struct Denoted_Type *definition);- struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object);+ struct AST_Object_Declaration* get_object_declaration_tree(struct Denoted_Object *object,struct AST_Expression *initialiser);struct AST_Function_Declaration* get_function_declaration_tree(struct Scope *scope,struct Denoted_Function *function);- struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct Translation_Data *translation_data);+ struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct AST_Compound_Statement *function_body,struct Translation_Data *translation_data);struct AST_Translation_Unit* get_translation_unit_tree();- _Bool ast_is_a_constant_expression(struct AST *ast,struct Translation_Data *translation_data);void delete_ast(struct AST* ast);void delete_ast_error(struct AST_Error *error);F diff --git a/src/semantics/constraints/constraints.h b/src/semantics/constraints/constraints.h --- a/src/semantics/constraints/constraints.h +++ b/src/semantics/constraints/constraints.h#ifndef WONKY_CONSTRAINTS_H#define WONKY_CONSTRAINTS_H WONKY_CONSTRAINTS_H- #include<expression_constraints.h>- #include<statement_constraints.h>+ #include <expression_constraints.h>+ #include <statement_constraints.h>+ #include <linkage_constraints.h>#endifF diff --git a/src/semantics/constraints/linkage_constraints.c b/src/semantics/constraints/linkage_constraints.c new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/linkage_constraints.c+ #ifndef WONKY_LINKAGE_CONSTRAINTS_C+ #define WONKY_LINKAGE_CONSTRAINTS_C WONKY_LINKAGE_CONSTRAINTS_C+ #include <linkage_constraints.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)+ {+ struct Linkage *linkage;+ struct Denoted_Object *hold_object;++ assert(current->type!=FUNCTION_SCOPE);++ if(previous_denoted_with_same_id==NULL) /*NOTE*/+ return 1;++ if(previous_denoted_with_same_id->denotation!=DT_Object)+ {+ push_translation_error("redeclaration of %D",translation_data,denoted_object);+ push_translation_note("previously declared as %D",translation_data,previous_denoted_with_same_id);+ return 0;+ }++ hold_object=(struct Denoted_Object*)previous_denoted_with_same_id;++ if(hold_object->linkage==LINKAGE_NONE)+ {+ push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);+ return 0;+ }++ if(denoted_object->linkage==LINKAGE_NONE)+ {+ push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);+ return 0;+ }else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)+ {+ 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);+++ if(hold_object!=NULL)+ {+ if(hold_object->denotation!=DT_Object)+ {+ 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))+ {+ 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);+ return 0;+ }++ }else+ {+ return 1;+ }+ }else+ {+ assert(0);+ }++ }+ _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)+ {+ struct Linkage *linkage;+ struct Denoted_Function *hold_function;++ assert(current->type!=FUNCTION_SCOPE);++ if(previous_denoted_with_same_id==NULL)+ return 1;++ if(denoted_function->linkage==LINKAGE_NONE)+ {+ push_translation_error("redeclaration of %D",translation_data,denoted_function);+ push_translation_note("previously declared as %D",translation_data,previous_denoted_with_same_id);+ return 0;+ }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);++ if(hold_function!=NULL)+ {+ if(hold_function->denotation!=DT_Function)+ {+ push_translation_error("linking an function to a object",translation_data);+ return 0;+ }+ 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+ {+ assert(0);+ }+ }+ #endifF diff --git a/src/semantics/constraints/linkage_constraints.h b/src/semantics/constraints/linkage_constraints.h new file mode 100644 --- /dev/null +++ b/src/semantics/constraints/linkage_constraints.h+ #ifndef WONKY_LINKAGE_CONSTRAINTS_H+ #define WONKY_LINKAGE_CONSTRAINTS_H WONKY_LINKAGE_CONSTRAINTS_H++ #include <program.h>+ #include <scope.h>+ #include <denoted.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);+ #endifF diff --git a/src/semantics/constraints/statement_constraints.c b/src/semantics/constraints/statement_constraints.c --- a/src/semantics/constraints/statement_constraints.c +++ b/src/semantics/constraints/statement_constraints.creturn 0;}assert(case_statement->control!=NULL);++ /*if(!ast_is_a_constant_expression((struct AST*)case_statement->control,translation_data)){push_translation_error("control expression in case statement is not a constant expression",translation_data);return 0;}+ */return 1;}_Bool constraint_check_labeled_statement(struct AST_Labeled_Statement *label,struct Translation_Data *translation_data)F diff --git a/src/semantics/identifiers/denoted.c b/src/semantics/identifiers/denoted.c --- a/src/semantics/identifiers/denoted.c +++ b/src/semantics/identifiers/denoted.cret->type=type;ret->location=NULL;ret->function_specifier=fs;- ret->body=NULL;ret->function_scope=NULL;return (struct Denoted*)ret;ret->id=id;ret->object=get_object(type,sc);-- ret->initializer=initializer;-return (struct Denoted*)ret;}{if(function->id!=NULL)free(function->id);- if(function->body!=NULL)- delete_ast_compound_statement(function->body);free(function);}void delete_denoted_object(struct Denoted_Object *object)free(object->id);if(object->object!=NULL)delete_object(object->object);- if(object->initializer!=NULL)- delete_ast(object->initializer);free(object);}void delete_denoted_typedef(struct Denoted_Type *typedefed)F diff --git a/src/semantics/identifiers/denoted.h b/src/semantics/identifiers/denoted.h --- a/src/semantics/identifiers/denoted.h +++ b/src/semantics/identifiers/denoted.henum Function_Specifier function_specifier;struct Function_Scope *function_scope;- struct AST_Compound_Statement *body;};struct Denoted_Object{struct token *id;struct Object *object;-- struct AST *initializer;};struct Denoted_Type{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.cdenoted_function->linkage=( (hold_function->linkage==LINKAGE_NONE) ? LINKAGE_EXTERNAL : hold_function->linkage);}else{- push_translation_error("linking mismatching things",translation_data);+ push_translation_error("mismtatching types for %t",translation_data,denoted_function->id);+ push_translation_note("first it was declared with type %T",translation_data,hold_function->type);+ push_translation_note("now it's declared with type %T",translation_data,denoted_function->type);return;}}elseF 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#ifndef WONKY_SCOPE_C#define WONKY_SCOPE_C WONKY_SCOPE_C- #include "scope.h"+ #include <scope.h>struct Scope* get_normal_scope(struct Scope *parent,enum Scope_Type type)}- #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object){- #define PO_ERROR(msg) push_translation_error(msg,translation_data,denoted_object->id);delete_denoted_object(denoted_object);return;+ struct Denoted *hold_previous;++ assert(current->type!=FUNCTION_SCOPE);- struct Denoted_Object *hold_object;- struct Linkage *linkage;++resolve_object_linkage(current,translation_data,denoted_object);- if(has_new_errors(translation_data))- {- push_translation_note("in declaration %D",translation_data,denoted_object);- delete_denoted_object(denoted_object);- return;- }- hold_object=CHECK_AND_PUSH(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary);- if(hold_object!=NULL && hold_object->linkage==LINKAGE_NONE)- {- push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);- delete_denoted_object(denoted_object);- return;- }+ hold_previous=check_and_push_id(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary,denoted_object->id);- if(denoted_object->linkage==LINKAGE_NONE)- {- if(hold_object!=NULL)- {- push_translation_error("redeclaration of identifier %t",translation_data,denoted_object->id);- delete_denoted_object(denoted_object);- return;- }- }else if(denoted_object->linkage==LINKAGE_EXTERNAL || denoted_object->linkage==LINKAGE_INTERNAL)- {- linkage=(denoted_object->linkage==LINKAGE_EXTERNAL?translation_data->external_linkage:translation_data->internal_linkage);- hold_object=CHECK_AND_PUSH(denoted_object,&linkage->ids);- if(hold_object!=NULL)- {- if(hold_object->denotation!=DT_Object)- {- push_translation_error("linking an object to a function %D",translation_data,denoted_object);- push_translation_note("linking against %D",translation_data,hold_object);- delete_denoted_object(denoted_object);- return;- }else if(!types_are_identical(hold_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);- delete_denoted_object(denoted_object);- return;- }else if(denoted_object->initializer!=NULL)- {- if(hold_object->initializer==NULL)- hold_object->initializer=denoted_object->initializer;- else- {PO_ERROR("two initialisers for static storage duration object");}- //delete_denoted_object(denoted_object);- }- }- }else+ if(has_new_errors(translation_data) || !constraint_check_object_linkage(denoted_object,hold_previous,current,translation_data) ){- assert(0);+ translation_data->number_of_errors_when_last_checked--; /*TODO make a new function for this for gods sake*/+ //delete_denoted_object(denoted_object);}- #undef PO_ERROR}void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function){- #define PF_ERROR(msg) delete_denoted_function(denoted_function);push_translation_error(msg,translation_data);return;+ struct Denoted *hold_previous;++ assert(current->type!=FUNCTION_SCOPE);+- struct Denoted_Function *hold_function;- struct Linkage *linkage;resolve_function_linkage(current,translation_data,denoted_function);- if(has_new_errors(translation_data))- {PF_ERROR("in declaration");}- hold_function=CHECK_AND_PUSH(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary);- if(denoted_function->linkage==LINKAGE_NONE)- {- if(hold_function!=NULL)- {PF_ERROR("id with function type without linkage");}- }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(denoted_function,&linkage->ids);- if(hold_function!=NULL)- {- if(hold_function->denotation!=DT_Function)- {PF_ERROR("linking an function to a object");}- if(!types_are_identical(hold_function->type,denoted_function->type))- {PF_ERROR("linking functions with mismatching types");}- if(hold_function->body!=NULL && denoted_function->body!=NULL)- {PF_ERROR("redefinition of a function");}- if(denoted_function->body!=NULL)- {- hold_function->body=denoted_function->body;- denoted_function->body=NULL;- // delete_denoted_function(denoted_function);- }- }- }else+ hold_previous=check_and_push_id(denoted_function,&AS_NORMAL_SCOPE(current)->ordinary,denoted_function->id);++ if(has_new_errors(translation_data) || !constraint_check_function_linkage(denoted_function,hold_previous,current,translation_data)){- assert(0);+ //delete_denoted_function(denoted_function);+ translation_data->number_of_errors_when_last_checked--;}-- #undef PF_ERROR}+ #define CHECK_AND_PUSH(thing,scope) Map_Check_And_Push(scope,thing->id->data,thing->id->data_size,thing)void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Type *denoted_typedef){struct Denoted *hold_denotated;push_translation_error("redefinition of tag",translation_data);}}+void push_denoted_enum_constant(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Enum_Const *denoted_enum_constant){struct Denoted *hold_denotated;push_translation_error("redefinition of tag",translation_data);}}- #undef CHECK_AND_PUSH+ void* check_and_push_id(void *data,struct Map *scope_map,struct token *id)+ {+ return Map_Check_And_Push(scope_map,id->data,id->data_size,data);+ }#endifF diff --git a/src/semantics/identifiers/scope.h b/src/semantics/identifiers/scope.h --- a/src/semantics/identifiers/scope.h +++ b/src/semantics/identifiers/scope.h#include <denoted.h>#include <location.h>#include <queue.h>+ #include <constraints.h>enum Scope_Type;+ void* check_and_push_id(void *data,struct Map *scope_map,struct token *id);+_Bool check_if_typedefed(struct Scope* scope,struct token *id);#endifF diff --git a/src/semantics/value/constant.c b/src/semantics/value/constant.c --- a/src/semantics/value/constant.c +++ b/src/semantics/value/constant.c}struct Constant* extract_literal_integer_dec(struct token *token,struct Translation_Data *translation_data){- /*the sign is acounted for during parsing*/+ /*the sign is acounted for during parsing ( not lexing )*/unsigned long long int cache=0;unsigned long long int *ret_component;struct Constant *ret;}+ struct Constant* extract_literal_integer_octal(struct token *token,struct Translation_Data *translation_data)+ {+ unsigned long long int cache=0;+ unsigned long long int *ret_component;+ struct Constant *ret;+ size_t i;++ ret_component=malloc(sizeof(unsigned long long int));+ ret=malloc(sizeof(struct Constant));++ for(i=0;i<token->data_size;++i)+ cache*=8 , cache+=token->data[i]-'0';++ *ret_component=cache;+ ret->value=ret_component;+ ret->type=(struct Type*)get_type_insecure(TS_INT,TSIGN_NONE,TC_NONE,INT_SIZE,translation_data);++ return ret;+ }struct Constant* extract_literal_integer_hex(struct token *token,struct Translation_Data *translation_data){unsigned long long int cache=0;F diff --git a/src/semantics/value/constant.h b/src/semantics/value/constant.h --- a/src/semantics/value/constant.h +++ b/src/semantics/value/constant.h};struct Constant* extract_constant(struct token *token,struct Translation_Data *translation_data);+ struct Constant* extract_literal_integer_octal(struct token *token,struct Translation_Data *translation_data);struct Constant* extract_literal_integer_dec(struct token *token,struct Translation_Data *translation_data);struct Constant* extract_literal_integer_hex(struct token *token,struct Translation_Data *translation_data);struct Constant* extract_literal_double_dec(struct token *token,struct Translation_Data *translation_data);++ struct Constant* get_unsigned_int_constant();+ struct Constant* get_signed_int_constant();++char ast_is_null_pointer_constant(struct AST *tree);char constant_is_null_pointer(struct Constant *constant);F diff --git a/src/semantics/value/evaluation.c b/src/semantics/value/evaluation.c --- a/src/semantics/value/evaluation.c +++ b/src/semantics/value/evaluation.c- #ifndef WONKY_SEMANTICS_C- #define WONKY_SEMANTICS_C WONKY_SEMANTICS_C+ #ifndef WONKY_EVALUATION_C+ #define WONKY_EVALUATION_C WONKY_EVALUATION_C#include <evaluation.h>+ /*Returns NULL if it can reduce expression to a constant*/+ struct Constant* try_to_evaluate_expression(struct AST_Expression *expression,struct Translation_Data *translation_data)+ {+ switch(expression->type)+ {+ case OP_ADDITION:++++ default:+ return NULL;+ }+ assert(0);+ }++++++++long long int evaluate_const_expression_integer(struct AST *expression,struct Translation_Data *translation_data){F diff --git a/src/semantics/value/evaluation.h b/src/semantics/value/evaluation.h --- a/src/semantics/value/evaluation.h +++ b/src/semantics/value/evaluation.h- #ifndef WONKY_SEMANTICS_H- #define WONKY_SEMANTICS_H WONKY_SEMANTICS_H+ #ifndef WONKY_EVALUATION_H+ #define WONKY_EVALUATION_H WONKY_EVALUATION_H#include <ast.h>+ #include <constant.h>#include <lexer.h>#include <program.h>++ struct Constant* try_to_evaluate_expression(struct AST_Expression *expression,struct Translation_Data *translation_data);+++long long int evaluate_const_expression_integer(struct AST *expression,struct Translation_Data *translation_data);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/*TODO !!!*/_Bool types_are_identical(struct Type *a,struct Type *b){- return a==b;+ if(a->specifier!=b->specifier)+ return 0;++ switch(a->specifier)+ {+ case TS_VOID:+ case TS_CHAR:+ case TS_INT:+ case TS_FLOAT:+ case TS_DOUBLE:+ return 1;++ case TS_UNION:+ case TS_STRUCT:+ return 1;+ case TS_ENUM:+ return 1;+ case TS_POINTER:+ {+ struct Type_Pointer *ap,*bp;+ ap=(struct Type_Pointer*)a;+ bp=(struct Type_Pointer*)b;++ return+ types_are_identical(ap->points_to,bp->points_to)+ &&+ ap->is_const==bp->is_const+ &&+ ap->is_volatile==bp->is_volatile+ ;++ }+ case TS_ARRAY:+ {+ struct Type_Array *aa,*ba;+ aa=(struct Type_Array*)a;+ ba=(struct Type_Array*)b;+ return+ types_are_identical(aa->is_array_of,ba->is_array_of)+ &&+ aa->number_of_elements==ba->number_of_elements+ ;+ }+ case TS_FUNC:+ {+ struct Type_Function *af,*bf;+ size_t i;++ af=(struct Type_Function*)a;+ bf=(struct Type_Function*)b;++ if(af->number_of_arguments!=bf->number_of_arguments+ || !types_are_identical(af->return_type,bf->return_type))+ return 0;++ for(i=0;i<af->number_of_arguments;++i)+ {+ if(!types_are_identical(af->arguments[i]->object->type,bf->arguments[i]->object->type))+ return 0;+ }+ return 1;+ }+ default:+ return 0;+ }+ assert(0);}/* 6.2.7* two types have compatible type if their types are the same.- * Additional+ * Additionally ... TODO** */_Bool types_are_compatible(struct Type *a,struct Type *b)F diff --git a/src/semantics/value/type.h b/src/semantics/value/type.h --- a/src/semantics/value/type.h +++ b/src/semantics/value/type.hsize_t number_of_elements;struct Type *is_array_of;};+ struct Type_Variable_Length_Array+ {+ enum Type_Specifier specifier;+ struct Map *node;+ size_t size;+ struct AST_Expression *number_of_elements;+ struct Type *is_array_of;+ };struct Type_Function{enum Type_Specifier specifier;F diff --git a/src/semantics/value/type.hh b/src/semantics/value/type.hh --- a/src/semantics/value/type.hh +++ b/src/semantics/value/type.hhstruct Type_Basic;struct Type_Pointer;struct Type_Array;+ struct Type_Variable_Length_Array;struct Type_Function;struct Type_Enum;struct Enum;