#ifndef WONKY_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;
}
wonky_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;
}
_Bool constraint_check_return_statement(struct AST *return_expression,struct Type *return_type,struct Translation_Data *translation_data)
{
if(return_expression==NULL)
{
return 1;
}else if(return_expression->type==ERROR || return_type->specifier==TS_ERROR )
{
return 0;
}else
{
struct Type *expression_type;
struct Expression_Value *value;
value=((struct AST_Expression*)return_expression)->value;
expression_type=extract_expresion_value_type(value);
if(!types_are_identical(expression_type,return_type))
{
push_translation_error("Returned expression should have %T type, got %T instead",translation_data,return_type,expression_type);
return 0;
}else
{
return 1;
}
}
wonky_assert(SHOULD_NOT_REACH_HERE);
}
_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;
}
_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;
}
}
#endif