F 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.cif(lab->type!=ST_LABEL)print_ast_enum(out,lab->type);if(lab->label!=NULL)- print_token(out,lab->label);- fprintf(out,":\n");- print_ast(out,(struct AST*)lab->statement);+ print_denoted(out,(struct Denoted*)lab->label);}void print_compound_statement_tree(FILE *out,struct AST_Compound_Statement *comp){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.chold_function->body=(struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,(struct Scope*)function_type->function_prototype_scope,NULL,NULL);- Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold));+ Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold,translation_data));break;}/*this is a function declaration*/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.ccase KW_ID:if(check(translation_data,KW_COLUMN,1)){- return parse_finish_labeled_statement(translation_data,scope,ST_LABEL,upper_loop,upper_switch);+ return parse_finish_labeled_statement(translation_data,scope,upper_loop,upper_switch);}else{return parse_expression_statement(translation_data,scope,upper_loop,upper_switch);if(check(translation_data,KW_ID,0)){- ret=(struct AST*)get_goto_statement_tree(Queue_Pop(translation_data->tokens),scope);+ ret=(struct AST*)get_goto_statement_tree(Queue_Pop(translation_data->tokens),scope,translation_data);if(get_and_check(translation_data,KW_SEMI_COLUMN)){return ret;else{push_translation_error(" label expected in goto statement",translation_data);- return (struct AST*)get_error_tree((struct AST*)get_goto_statement_tree(NULL,NULL));+ return (struct AST*)get_error_tree(NULL);}}id:statement*/- struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,enum AST_Type type,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch){- struct AST_Labeled_Statement *ret;- if(check(translation_data,KW_ID,0))- {- ret=get_labeled_statement_tree(Queue_Pop(translation_data->tokens),NULL,type,translation_data,scope);- if(get_and_check(translation_data,KW_COLUMN))- {- ret->statement=parse_statement(translation_data,scope,upper_loop,upper_switch);- return (struct AST*)ret;- }else- {- push_translation_error(" ':' expected in labeled statement",translation_data);- return (struct AST*)get_error_tree((struct AST*)ret);- }- }else- {- push_translation_error(" label expected in labeled statement",translation_data);- return (struct AST*)get_error_tree(NULL);- }+ struct AST *hold_statement;+ struct token *hold_id;+ /*id and ':' are checked for in the parse_statement function*/++ hold_id=Queue_Pop(translation_data->tokens);+ chomp(translation_data); /* ':' */+ hold_statement=parse_statement(translation_data,scope,upper_loop,upper_switch);++ return (struct AST*)get_labeled_statement_tree(hold_id,hold_statement,ST_LABEL,translation_data,scope);}/**/struct AST* parse_finish_default_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch){- struct AST_Labeled_Statement *ret;- ret=get_labeled_statement_tree(NULL,NULL,ST_DEFAULT,translation_data,scope);+ struct AST *statement;if(get_and_check(translation_data,KW_COLUMN)){- ret->statement=parse_statement(translation_data,scope,upper_loop,upper_switch);- return (struct AST*)ret;+ statement=parse_statement(translation_data,scope,upper_loop,upper_switch);+ return (struct AST*)get_default_statement_tree(statement,translation_data);}else{push_translation_error(" ':' expected in default statement",translation_data);- return (struct AST*)get_error_tree((struct AST*)ret);+ return (struct AST*)get_error_tree((struct AST*)NULL);}}/*F diff --git a/src/frontend/parse/parse_statement.h b/src/frontend/parse/parse_statement.h --- a/src/frontend/parse/parse_statement.h +++ b/src/frontend/parse/parse_statement.hstruct AST* parse_finish_break_statement(struct Translation_Data* translation_data,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);struct AST* parse_finish_return_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);struct AST* parse_expression_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,enum AST_Type type,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);+ struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);struct AST* parse_finish_case_statement(struct Translation_Data *translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);F diff --git a/src/program/gcc_error.c b/src/program/gcc_error.c --- a/src/program/gcc_error.c +++ b/src/program/gcc_error.cchar *ret;size_t filename_length;- filename_length=gstrlen(filename);+ if(filename!=NULL)+ filename_length=gstrlen(filename);+ else+ filename_length=sizeof("NULL")+100;+ret=calloc(filename_length+64,1);sprintf(ret,"%s %zu:%zu ",filename,line,column);F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.cstruct AST_Labeled_Statement *ret;ret=malloc(sizeof(struct AST_Labeled_Statement));ret->type=type;- ret->label=label;++ ret->label=(struct Denoted_Statement*)push_label(scope,label,statement,translation_data);++ return ret;+ }+ struct AST_Default_Statement* get_default_statement_tree(struct AST *statement,struct Translation_Data *translation_data)+ {+ struct AST_Default_Statement *ret;+ ret=malloc(sizeof(struct AST_Default_Statement));+ ret->type=ST_DEFAULT;ret->statement=statement;return ret;}}- struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope)+ struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope,struct Translation_Data *translation_data){struct AST_Goto_Statement *ret;struct Denoted_Statement *hold_statement;hold_statement=check_label(scope,label);if(hold_statement==NULL){- hold_statement=(struct Denoted_Statement*)get_denoted_statement(label,NULL,NULL);+ push_label(scope,label,NULL,translation_data);+ hold_statement=check_label(scope,label);}ret->label=hold_statement;return ret;}- struct AST_Function_Definition* get_function_definition_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 *ret;ret=malloc(sizeof(struct AST_Function_Definition));ret->type=ST_FUNCTION_DEFINITION;ret->function=function;- return ret;++ if(!constraint_check_function_definition(ret,translation_data))+ return (struct AST_Function_Definition*)get_error_tree((struct AST*)ret);+ else+ return ret;}struct AST_Function_Declaration* get_function_declaration_tree(struct Scope *scope,struct Denoted_Function *function)void delete_ast_labeled_statement(struct AST_Labeled_Statement *labeled_statement){if(labeled_statement->label!=NULL)- free(labeled_statement->label);- if(labeled_statement->statement!=NULL)- delete_ast(labeled_statement->statement);+ delete_denoted((struct Denoted*)labeled_statement->label);free(labeled_statement);}void delete_ast_compound_statement(struct AST_Compound_Statement *compound_statement)F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.hstruct AST_Labeled_Statement{enum AST_Type type;- struct token *label;- struct AST *statement;+ struct Denoted_Statement *label;};struct AST_Case_Statement{struct AST_Expression *expression;struct AST *statement;};+ struct AST_Default_Statement+ {+ enum AST_Type type;+ struct AST *statement;+ };struct AST_Compound_Statement{enum AST_Type type;- struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,enum AST_Type type,struct Translation_Data *translation_data,struct Scope *scope);+ struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST *statement,enum AST_Type type,struct Translation_Data *translation_data,struct Scope *scope);+ struct AST_Default_Statement* get_default_statement_tree(struct AST *statement,struct Translation_Data *translation_data);struct AST_Compound_Statement* get_compound_statement_tree(struct Scope *parent_scope);struct AST_If_Statement* get_if_statement_tree();struct AST_Switch_Statement* get_switch_statement_tree();struct AST_Do_While_Statement* get_do_while_statement_tree();struct AST_For_Statement* get_for_statement_tree();struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression,struct Translation_Data *translation_data,struct Scope *scope);- struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope);+ 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_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 AST_Function_Definition* get_function_definition_tree(struct Scope *scope,struct Denoted_Function *function,struct Translation_Data *translation_data);struct AST_Translation_Unit* get_translation_unit_tree();F 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.c#define WONKY_STATEMENT_CONSTRAINTS_C WONKY_STATEMENT_CONSTRAINTS_C#include <statement_constraints.h>+ _Bool constraint_check_labeled_statement(struct AST_Labeled_Statement *label,struct Translation_Data *translation_data)+ {+ return 1;+ }_Bool constraint_check_return_statement(struct AST *return_expression,struct Type *return_type,struct Translation_Data *translation_data){assert(0);}+ _Bool constraint_check_function_definition(struct AST_Function_Definition *function,struct Translation_Data *translation_data)+ {+ struct Function_Scope *function_scope;+ struct Queue_Node *it;++ function_scope=function->function->function_scope;++ for(it=function_scope->label_order->first;it!=NULL;it=it->prev)+ {+ if(!denoted_statement_is_declared((struct Denoted_Statement*)it->data))+ {+ push_translation_error("Label %t is used but not declared",translation_data,+ ((struct Denoted_Statement*)it->data)->label+ );+ return 0;+ }+ if(!constraint_check_labeled_statement(((struct AST_Labeled_Statement*)it->data),translation_data))+ return 0;+ }++ return 1;+ }#endifF diff --git a/src/semantics/constraints/statement_constraints.h b/src/semantics/constraints/statement_constraints.h --- a/src/semantics/constraints/statement_constraints.h +++ b/src/semantics/constraints/statement_constraints.h/*_Bool constraint_check_case_statement(struct ,struct Translation_Data *translation_data);*//*_Bool constraint_check_default(struct ,struct Translation_Data *translation_data);*/- _Bool constraint_check_label(struct AST_Labeled_Statement *label,struct AST_Compound_Statement *function_block,struct Translation_Data *translation_data);+ _Bool constraint_check_labeled_statement(struct AST_Labeled_Statement *label,struct Translation_Data *translation_data);/*must have scallar controlling expression*/_Bool constraint_check_if_statement(struct AST_If_Statement *if_statement,struct Translation_Data *translation_data);/*must be in a function and must return with the function return type , empty expressions are premmited under functions returning void*/_Bool constraint_check_return_statement(struct AST *return_expression,struct Type *return_type,struct Translation_Data *translation_data);+ _Bool constraint_check_compound_statement(struct AST_Compound_Statement *block,struct Translation_Data *translation_data);++ /*Not really a statement*/+ _Bool constraint_check_function_definition(struct AST_Function_Definition *function,struct Translation_Data *translation_data);#endifF 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.c+ _Bool denoted_statement_is_declared(struct Denoted_Statement *statement)+ {+ return statement->statement!=NULL;+ }#endifF 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.hvoid delete_denoted_base(struct Denoted_Base *base);void delete_denoted_statement(struct Denoted_Statement *statement);-enum Storage_Class_Specifier get_denoted_function_storage_class(struct Denoted_Function *function);++ _Bool denoted_statement_is_declared(struct Denoted_Statement *statement);#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.creturn 1;}- void push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data)+ struct Denoted* push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data){struct Denoted_Statement *hold_statement;struct Function_Scope *current_function_scope;if(hold_statement->statement!=NULL){push_translation_error("Redeclaration of label id %t",translation_data,label);- return;++ return get_denoted_error((struct Denoted*)hold_statement);}else{assert(hold_statement->label!=NULL);/*note the use of the current scope instead of the function scope*/hold_statement->previous_denoted_object=get_last_known_denoted_object((struct Normal_Scope*)current);- assert(hold_statement->previous_denoted_object->denotation==DT_Object);+ assert(hold_statement->previous_denoted_object==NULL || hold_statement->previous_denoted_object->denotation==DT_Object);++ return (struct Denoted*)hold_statement;}}else{hold_statement=(struct Denoted_Statement*)get_denoted_statement(label,statement,get_last_known_denoted_object((struct Normal_Scope*)current));Map_Push(¤t_function_scope->labels,label->data,label->data_size,hold_statement);+ Queue_Push(current_function_scope->label_order,hold_statement);+++ return (struct Denoted*)hold_statement;}++ assert(0);}F 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.hvoid* check_ordinary(struct Scope *current,struct token *id);- void push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data);+ /*+ * a little bit different from the others because gotos can use forward declared labels+ * so to not have a second passing of the ast we push the label with a null statement pointer+ * when we 'declare' the label we push the label with a non null statement and get a constructed denoted statement+ * that might have been made and pushed from a previous goto.+ * A reference of all the gotos jumping to the label are held in the denoted statement struct so we can do+ * constraint checking in the function definition constraint check ( that being if there are no variable length arrays be+ * tween goto and label :X)+ *+ * CAN THROW A DENOTED ERROR IF THERE IS REDECLARATION!+ *+ * TODO refactor this into something more sensible+ *+ * */+ struct Denoted* push_label(struct Scope *current,struct token *label,struct AST *statement,struct Translation_Data *translation_data);+void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object);void push_function(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Function *denoted_function);void push_typedef(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Type *denoted_typedef);