WONKY



LOG | FILES | OVERVIEW


#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