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.cfunction_type->function_prototype_scope->parent=(struct Scope*)hold_function->function_scope;- hold_function->body=- (struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,(struct Scope*)function_type->function_prototype_scope,NULL,NULL);+ hold_function->body+ =+ (struct AST_Compound_Statement*)+ parse_finish_compound_statement(+ translation_data,+ (struct Scope*)function_type->function_prototype_scope,+ &(struct Parse_Statement_Data)+ {+ .break_statement_owner=NULL,+ .continue_statement_owner=NULL,+ .current_switch_statement=NULL,+ }+ );+Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold,translation_data));break;}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#include "parse_statement.h"- struct AST* parse_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){if(translation_data->tokens->size==0)return (struct AST*)get_error_tree(NULL);case KW_OPEN_CURLY:chomp(translation_data);- return parse_finish_compound_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_compound_statement(translation_data,scope,parse_data);case KW_IF:chomp(translation_data);- return parse_finish_if_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_if_statement(translation_data,scope,parse_data);case KW_SWITCH:chomp(translation_data);- return parse_finish_switch_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_switch_statement(translation_data,scope,parse_data);case KW_WHILE:chomp(translation_data);- return parse_finish_while_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_while_statement(translation_data,scope,parse_data);case KW_DO:chomp(translation_data);- return parse_finish_do_while_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_do_while_statement(translation_data,scope,parse_data);case KW_FOR:chomp(translation_data);- return parse_finish_for_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_for_statement(translation_data,scope,parse_data);case KW_GOTO:chomp(translation_data);- return parse_finish_goto_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_goto_statement(translation_data,scope,parse_data);case KW_CASE:chomp(translation_data);- return parse_finish_case_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_case_statement(translation_data,scope,parse_data);case KW_DEFAULT:chomp(translation_data);- return parse_finish_default_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_default_statement(translation_data,scope,parse_data);case KW_ID:if(check(translation_data,KW_COLUMN,1)){- return parse_finish_labeled_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_labeled_statement(translation_data,scope,parse_data);}else{- return parse_expression_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_expression_statement(translation_data,scope,parse_data);}case KW_CONTINUE:chomp(translation_data);- return parse_finish_continue_statement(translation_data,upper_loop,upper_switch);+ return parse_finish_continue_statement(translation_data,parse_data);case KW_BREAK:chomp(translation_data);- return parse_finish_break_statement(translation_data,upper_loop,upper_switch);+ return parse_finish_break_statement(translation_data,parse_data);case KW_RETURN:chomp(translation_data);- return parse_finish_return_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_finish_return_statement(translation_data,scope,parse_data);default:- return parse_expression_statement(translation_data,scope,upper_loop,upper_switch);+ return parse_expression_statement(translation_data,scope,parse_data);}/*( declaration | statement )* }*/- struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_Compound_Statement *hold;hold=get_compound_statement_tree(scope);parse_declaration(translation_data,hold->scope,&hold->components,0);}else{- Queue_Push(&hold->components,parse_statement(translation_data,hold->scope,upper_loop,upper_switch));+ Queue_Push(&hold->components,parse_statement(translation_data,hold->scope,parse_data));}if(has_new_errors(translation_data))chase_next_semicolumn(translation_data);( expression ) statement( expression ) statement else statement*/- struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_If_Statement *hold;hold=get_if_statement_tree();hold->condition=parse_expression(translation_data,scope);if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- hold->body_statement=parse_statement(translation_data,scope,upper_loop,upper_switch);+ hold->body_statement=parse_statement(translation_data,scope,parse_data);}else{push_translation_error(" ')' expected",translation_data);}if(get_and_check(translation_data,KW_ELSE)){- hold->else_statement=parse_statement(translation_data,scope,upper_loop,upper_switch);+ hold->else_statement=parse_statement(translation_data,scope,parse_data);return (struct AST*)hold;}else{/*( expression ) statement*/- struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_Switch_Statement *hold;- hold=get_switch_statement_tree();+ struct AST_Expression *hold_control_expression;+ struct AST *hold_body_statement;+if(get_and_check(translation_data,KW_OPEN_NORMAL)){- hold->condition=parse_expression(translation_data,scope);+ hold_control_expression=(struct AST_Expression*)parse_expression(translation_data,scope);if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- hold->body_statement=parse_statement(translation_data,scope,upper_loop,hold);+ hold_body_statement+ =+ parse_statement(+ translation_data,+ scope,+ &(struct Parse_Statement_Data)+ {+ .break_statement_owner=(struct AST*)hold,+ .continue_statement_owner=parse_data->continue_statement_owner,+ .current_switch_statement=hold,+ }+ );++ hold=get_switch_statement_tree(hold_control_expression,hold_body_statement);+ return (struct AST*)hold;}else{push_translation_error(" ')' expected",translation_data);- return (struct AST*)get_error_tree((struct AST*)hold);+ return (struct AST*)get_error_tree((struct AST*)hold_control_expression);}}else{push_translation_error(" '(' expected",translation_data);- return (struct AST*)get_error_tree((struct AST*)hold);+ return (struct AST*)get_error_tree((struct AST*)NULL);}- return (struct AST*)hold;+ assert(0);}/*( expression ) statement*/- struct AST* parse_finish_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_While_Statement *hold;hold=get_while_statement_tree();hold->condition=parse_expression(translation_data,scope);if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- hold->body_statement=parse_statement(translation_data,scope,(struct AST*)hold,upper_switch);+ hold->body_statement+ =+ parse_statement(+ translation_data,+ scope,+ &(struct Parse_Statement_Data)+ {+ .break_statement_owner=(struct AST*)hold,+ .continue_statement_owner=(struct AST*)hold,+ .current_switch_statement=parse_data->current_switch_statement,+ }+ );+ return (struct AST*)hold;}else{push_translation_error(" ')' expected",translation_data);return (struct AST*)get_error_tree((struct AST*)hold);}- return (struct AST*)hold;+ assert(0);+}/*statement while ( expression ) ;*/- struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_Do_While_Statement *hold;hold=get_do_while_statement_tree();- hold->body_statement=parse_statement(translation_data,scope,(struct AST*)hold,upper_switch);++ hold->body_statement+ =+ parse_statement(+ translation_data,+ scope,+ &(struct Parse_Statement_Data)+ {+ .break_statement_owner=(struct AST*)hold,+ .continue_statement_owner=(struct AST*)hold,+ .current_switch_statement=parse_data->current_switch_statement,+ }+ );+++if(get_and_check(translation_data,KW_WHILE) && get_and_check(translation_data,KW_OPEN_NORMAL)){hold->condition=parse_expression(translation_data,scope);/*( [ expression ] ; [ expression ] ; [ expression ] ) statement*/- struct AST* parse_finish_for_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_for_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_For_Statement *hold;hold=get_for_statement_tree();return (struct AST*)get_error_tree((struct AST*)hold);}- hold->initialisation=parse_expression_statement(translation_data,scope,upper_loop,upper_switch);- hold->condition=parse_expression_statement(translation_data,scope,upper_loop,upper_switch);+ hold->initialisation=parse_expression_statement(translation_data,scope,parse_data);+ hold->condition=parse_expression_statement(translation_data,scope,parse_data);+if(get_and_check(translation_data,KW_CLOSE_NORMAL)){hold->update=get_nop_tree();return (struct AST*)get_error_tree((struct AST*)hold);}}- hold->body_statement=parse_statement(translation_data,scope,(struct AST*)hold,upper_switch);+++ hold->body_statement+ =+ parse_statement(+ translation_data,+ scope,+ &(struct Parse_Statement_Data)+ {+ .break_statement_owner=(struct AST*)hold,+ .continue_statement_owner=(struct AST*)hold,+ .current_switch_statement=parse_data->current_switch_statement,+ }+ );+return (struct AST*)hold;}/*id ;*/- struct AST* parse_finish_goto_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_goto_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST* ret;/*;*/- struct AST* parse_finish_continue_statement(struct Translation_Data* translation_data,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_continue_statement(struct Translation_Data* translation_data,struct Parse_Statement_Data *parse_data){- struct AST *hold;- hold=malloc(sizeof(struct AST));- hold->type=ST_CONTINUE;+if(get_and_check(translation_data,KW_SEMI_COLUMN)){- return hold;+ return (struct AST*)get_break_continue_statement_tree(parse_data->continue_statement_owner,translation_data,ST_CONTINUE);}else{push_translation_error(" ';' expected",translation_data);- return (struct AST*)get_error_tree(hold);+ return (struct AST*)get_error_tree(NULL);}}/*;*/- struct AST* parse_finish_break_statement(struct Translation_Data* translation_data,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch)+ struct AST* parse_finish_break_statement(struct Translation_Data* translation_data,struct Parse_Statement_Data *parse_data){- struct AST *hold;- hold=malloc(sizeof(struct AST));- hold->type=ST_BREAK;if(get_and_check(translation_data,KW_SEMI_COLUMN)){- return hold;+ return (struct AST*)get_break_continue_statement_tree(parse_data->break_statement_owner,translation_data,ST_BREAK);}else{push_translation_error(" ';' expected",translation_data);- return (struct AST*)get_error_tree(hold);+ return (struct AST*)get_error_tree(NULL);}}/*id:statement*/- 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_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST *hold_statement;struct token *hold_id;hold_id=Queue_Pop(translation_data->tokens);chomp(translation_data); /* ':' */- hold_statement=parse_statement(translation_data,scope,upper_loop,upper_switch);+ hold_statement=parse_statement(translation_data,scope,parse_data);return (struct AST*)get_labeled_statement_tree(hold_id,hold_statement,ST_LABEL,translation_data,scope);}/*- constant :+ constant-expresssion :statement*/- struct AST* parse_finish_case_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 Parse_Statement_Data *parse_data){struct AST_Expression *hold_expression;struct AST *hold_statement;+ hold_expression=(struct AST_Expression*)parse_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_COLUMN))+ {+ hold_statement=parse_statement(translation_data,scope,parse_data);+ return (struct AST*)get_case_statement_tree(hold_statement,hold_expression,parse_data->current_switch_statement,translation_data);+ }else+ {+ push_translation_error(" ':' expected after expression in case statement",translation_data);+ return (struct AST*)get_error_tree((struct AST*)hold_expression);+ }+ assert(0);}/*:statement*/- 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* parse_finish_default_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST *statement;if(get_and_check(translation_data,KW_COLUMN)){- statement=parse_statement(translation_data,scope,upper_loop,upper_switch);+ statement=parse_statement(translation_data,scope,parse_data);return (struct AST*)get_default_statement_tree(statement,translation_data);}else{[ expression ] ;*/- 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_finish_return_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST_Return_Statement *hold;if(get_and_check(translation_data,KW_SEMI_COLUMN))[ expression ] ;*/- 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_expression_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data){struct AST *hold;if(get_and_check(translation_data,KW_SEMI_COLUMN))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.h#ifndef PARSE_WONKY_STATEMENT_H#define PARSE_WONKY_STATEMENT_H PARSE_WONKY_STATEMENT_H+ #include <parse_statement.hh>#include <scope.h>#include <ast.h>#include <queue.h>#include <program.h>+ struct Parse_Statement_Data+ {+ struct AST *break_statement_owner;+ struct AST *continue_statement_owner;+ struct AST_Switch_Statement *current_switch_statement;+ };- struct AST* parse_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_for_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_goto_statement(struct Translation_Data* translation_data,struct Scope *scope,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct AST* parse_finish_continue_statement(struct Translation_Data* translation_data,struct AST *upper_loop,struct AST_Switch_Statement *upper_switch);- struct 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,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);+ struct AST* parse_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_while_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_for_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_goto_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_continue_statement(struct Translation_Data* translation_data,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_break_statement(struct Translation_Data* translation_data,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_return_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_expression_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);+ struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);- 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* parse_finish_case_statement(struct Translation_Data *translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);++ struct AST* parse_finish_default_statement(struct Translation_Data* translation_data,struct Scope *scope,struct Parse_Statement_Data *parse_data);void chase_next_semicolumn(struct Translation_Data *translation_data);F diff --git a/src/frontend/parse/parse_statement.hh b/src/frontend/parse/parse_statement.hh new file mode 100644 --- /dev/null +++ b/src/frontend/parse/parse_statement.hh+ #ifndef PARSE_WONKY_STATEMENT_HH+ #define PARSE_WONKY_STATEMENT_HH PARSE_WONKY_STATEMENT_HH++ struct Parse_Statement_Data;++ #endifF diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.c}+ struct AST_Case_Statement* get_case_statement_tree(struct AST *statement,struct AST_Expression *control,struct AST_Switch_Statement *parent,struct Translation_Data *translation_data)+ {+ struct AST_Case_Statement *ret;+ ret=malloc(sizeof(struct AST_Case_Statement));++ ret->type=ST_CASE;+ ret->control=control;+ ret->statement=statement;++ if(constraint_check_case_statement(ret,parent,translation_data))+ return ret;+ else+ return (struct AST_Case_Statement*)get_error_tree((struct AST*)ret);++ }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 *ret;ret=malloc(sizeof(struct AST_Labeled_Statement));ret->type=type;-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)return ret;}+ struct AST_Break_Continue_Statement* get_break_continue_statement_tree(struct AST *parent,struct Translation_Data *translation_data,enum AST_Type break_or_continue)+ {+ struct AST_Break_Continue_Statement *ret;+ ret=malloc(sizeof(struct AST_Break_Continue_Statement));+ ret->type=break_or_continue;+ ret->parent=parent;+ if(constraint_check_break_continue_statement(ret,translation_data))+ return ret;+ else+ return (struct AST_Break_Continue_Statement*)get_error_tree((struct AST*)ret);+ }struct AST_Compound_Statement* get_compound_statement_tree(struct Scope *parent_scope){struct AST_Compound_Statement *ret;return ret;}- struct AST_Switch_Statement* get_switch_statement_tree()+ struct AST_Switch_Statement* get_switch_statement_tree(struct AST_Expression *condidion,struct AST *body_statement){struct AST_Switch_Statement *ret;+ret=malloc(sizeof(struct AST_Switch_Statement));+ ret->cases=malloc(sizeof(struct Queue));++ Queue_Init(ret->cases);+ret->type=ST_SWITCH;+ ret->condition=condidion;+ ret->body_statement=body_statement;+++return ret;}struct AST_While_Statement* get_while_statement_tree()return ret;}+ /*+ * TODO+ */+ _Bool ast_is_a_constant_expression(struct AST *ast,struct Translation_Data *translation_data)+ {+ return 0;+ }void delete_ast(struct AST* ast){delete_ast_goto_statemtent((struct AST_Goto_Statement*)ast);break;case ST_LABEL:- case ST_CASE:delete_ast_labeled_statement((struct AST_Labeled_Statement*)ast);break;+ case ST_CASE:+ delete_ast_case_statement((struct AST_Case_Statement*)ast);+ break;case ST_DEFAULT:+ delete_ast_default_statement((struct AST_Default_Statement*)ast);+ break;case ST_CONTINUE:case ST_BREAK:- /*I think it doesnt come with anything*/- free(ast);+ delete_ast_break_continue_statement((struct AST_Break_Continue_Statement*)ast);break;case ST_RETURN:delete_ast_return_statement((struct AST_Return_Statement*)ast);delete_denoted((struct Denoted*)labeled_statement->label);free(labeled_statement);}+ void delete_ast_default_statement(struct AST_Default_Statement *default_statement)+ {+ free(default_statement);+ }+ void delete_ast_break_continue_statement(struct AST_Break_Continue_Statement *break_continue)+ {+ free(break_continue);+ }void delete_ast_compound_statement(struct AST_Compound_Statement *compound_statement){if(compound_statement->scope!=NULL)void delete_ast_switch_statement(struct AST_Switch_Statement *switch_statement){if(switch_statement->condition!=NULL)- delete_ast(switch_statement->condition);+ delete_ast((struct AST*)switch_statement->condition);if(switch_statement->body_statement!=NULL)delete_ast(switch_statement->body_statement);++ while(switch_statement->cases->size>0)+ Queue_Pop(switch_statement->cases);++ free(switch_statement->cases);free(switch_statement);}+ void delete_ast_case_statement(struct AST_Case_Statement *case_statement)+ {+ if(case_statement->control)+ delete_ast((struct AST*)case_statement->control);+ if(case_statement->statement)+ delete_ast(case_statement->statement);+ free(case_statement);+ }void delete_ast_return_statement(struct AST_Return_Statement *return_statement){if(return_statement->return_expression!=NULL)F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.hstruct AST_Case_Statement{enum AST_Type type;- struct AST_Expression *expression;++ struct AST_Expression *control;struct AST *statement;};struct AST_Default_Statementenum AST_Type type;struct AST *statement;};+ struct AST_Break_Continue_Statement+ {+ enum AST_Type type;+ struct AST *parent;+ };struct AST_Compound_Statement{enum AST_Type type;struct AST_Switch_Statement{enum AST_Type type;- struct AST* condition;+ struct AST_Expression* condition;struct AST* body_statement;++ struct Queue *cases;};struct AST_Return_Statement{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_Case_Statement* get_case_statement_tree(struct AST *statement,struct AST_Expression *control,struct AST_Switch_Statement *parent,struct Translation_Data *translation_data);struct AST_Default_Statement* get_default_statement_tree(struct AST *statement,struct Translation_Data *translation_data);+ struct AST_Break_Continue_Statement* get_break_continue_statement_tree(struct AST *parent,struct Translation_Data *translation_data,enum AST_Type break_or_continue);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_Switch_Statement* get_switch_statement_tree(struct AST_Expression *condidion,struct AST *body_statement);struct AST_While_Statement* get_while_statement_tree();struct AST_Do_While_Statement* get_do_while_statement_tree();struct AST_For_Statement* get_for_statement_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);void delete_ast_declaration_error(struct AST_Declaration_Error *error);void delete_ast_designator_expression(struct AST_Designator *designator);void delete_ast_unary_expression(struct AST_Unary_Expression *unary_expression);void delete_ast_labeled_statement(struct AST_Labeled_Statement *labeled_statement);+ void delete_ast_default_statement(struct AST_Default_Statement *default_statement);+ void delete_ast_break_continue_statement(struct AST_Break_Continue_Statement *break_continue);void delete_ast_compound_statement(struct AST_Compound_Statement *compound_statement);void delete_ast_for_statement(struct AST_For_Statement *for_statement);void delete_ast_while_statemtent(struct AST_While_Statement *while_statement);void delete_ast_if_statemtent(struct AST_If_Statement *if_statement);void delete_ast_goto_statemtent(struct AST_Goto_Statement *goto_statement);void delete_ast_switch_statement(struct AST_Switch_Statement *switch_statement);+ void delete_ast_case_statement(struct AST_Case_Statement *case_statement);void delete_ast_return_statement(struct AST_Return_Statement *return_statement);void delete_ast_type_definition(struct AST_Type_Definition *type_definition);void delete_ast_object_declaration(struct AST_Object_Declaration *object_declaration);F diff --git a/src/semantics/ast.hh b/src/semantics/ast.hh --- a/src/semantics/ast.hh +++ b/src/semantics/ast.hhstruct AST_Designator;struct AST_Unary_Expression;struct AST_Labeled_Statement;+ struct AST_Case_Statement;+ struct AST_Default_Statement;+ struct AST_Break_Continue_Statement;struct AST_Compound_Statement;struct AST_For_Statement;struct AST_While_Statement;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_case_statement(struct AST_Case_Statement *case_statement,struct AST_Switch_Statement *parent,struct Translation_Data *translation_data)+ {+ if(parent==NULL)+ {+ push_translation_error("case statement used outside of a switch",translation_data);+ return 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){return 1;return 1;}+ _Bool constraint_check_break_continue_statement(struct AST_Break_Continue_Statement* break_statement,struct Translation_Data *translation_data)+ {+ if(break_statement->parent==NULL)+ {+ if(break_statement->type==ST_BREAK)+ push_translation_error("Using a break statement outside of a loop or switch statement",translation_data);+ else+ push_translation_error("Using a continue statement outside of a loop statement",translation_data);++ return 0;+ }else+ {+ 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_case_statement(struct AST_Case_Statement *case_statement,struct AST_Switch_Statement *parent,struct Translation_Data *translation_data);/*_Bool constraint_check_default(struct ,struct Translation_Data *translation_data);*/_Bool constraint_check_labeled_statement(struct AST_Labeled_Statement *label,struct Translation_Data *translation_data);_Bool constraint_check_for_statement(struct AST_For_Statement *for_statement,struct Translation_Data *translation_data);_Bool constraint_check_goto_statement(struct AST_Goto_Statement *goto_statement,struct Translation_Data *translation_data);- _Bool constraint_check_continue_statement(struct AST_Labeled_Statement *continue_statement,struct Translation_Data *translation_data);- _Bool constraint_check_break_statement(struct AST* break_statement,struct Translation_Data *translation_data);++ _Bool constraint_check_break_continue_statement(struct AST_Break_Continue_Statement* break_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);