WONKY



LOG | FILES | OVERVIEW


#ifndef WONKY_DENOTED_C
#define WONKY_DENOTED_C WONKY_DENOTED_C
#include <denoted.h>

struct Denoted* get_denoted_error(struct Denoted *error)
{
	struct Denoted_Error *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Error));
	ret->denotation=DT_Error;
	ret->error=error;

	return (struct Denoted*)ret;
}
struct Denoted_Base* get_denoted_base(struct Denotation_Prototype *prototype)
{
	struct Denoted_Base *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Base));
	ret->denotation=prototype->denotation;
	ret->id=NULL;
	ret->type=get_type_error(prototype->type);

	wonky_assert(is_valid_denoted_base(ret));
	return ret;
}
struct Denoted* get_denoted_function(struct identifier *id,struct Type *type,enum Function_Specifier fs)
{
	struct Denoted_Function *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Function));
	ret->denotation=DT_Function;
	ret->linkage=LINKAGE_NONE;
	ret->id=id;
	ret->type=type;
	ret->location=NULL;
	ret->function_specifier=fs;
	ret->function_scope=NULL;

	wonky_assert(is_valid_denoted_function(ret));
	return (struct Denoted*)ret;
}
struct Denoted* get_denoted_object(struct identifier *id, enum Storage_Class_Specifier sc,struct Type *type,struct AST *initializer)
{
	struct Denoted_Object *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Object));
	ret->denotation=DT_Object;
	ret->linkage=LINKAGE_NONE;
	ret->id=id;

	ret->object=get_object(type,sc);

	wonky_assert(is_valid_denoted_object(ret));
	return (struct Denoted*)ret;
}

struct Denoted* get_denoted_typedef(struct Denoted_Base *base)
{
	struct Denoted_Type *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Type));
	ret->denotation=DT_Typedef;
	ret->type=base->type;
	ret->id=base->id;

	wonky_assert(is_valid_denoted_type(ret));
	return (struct Denoted*)ret;
}
struct Denoted* get_denoted_enum_const_expr(struct identifier *id,struct Enum *parent,struct AST* expression,struct Translation_Data *translation_data)
{
	struct Denoted_Enum_Const *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Enum_Const));
	ret->denotation=DT_Enum_Constant;
	ret->id=id;
	ret->parent=parent;
	ret->expression=expression;
	ret->value=evaluate_const_expression_integer(expression,translation_data);

	wonky_assert(is_valid_denoted_enum_const(ret));
	return (struct Denoted*)ret;
	
}
struct Denoted* get_denoted_enum_const_num(struct identifier *id,struct Enum *parent,int value)
{
	struct Denoted_Enum_Const *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Enum_Const));
	ret->denotation=DT_Enum_Constant;
	ret->id=id;
	ret->parent=parent;
	ret->expression=NULL;
	ret->value=value;

	wonky_assert(is_valid_denoted_enum_const(ret));
	return (struct Denoted*)ret;
}
struct Denoted* get_denoted_enum(struct Enum *enumerator)
{
	struct Denoted_Enum *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Enum));
	ret->denotation=DT_Enum;
	ret->enumeration=enumerator;

	wonky_assert(is_valid_denoted_enum(ret));
	return (struct Denoted*)ret;
}
struct Denoted* get_denoted_struct_union(struct Struct_Union *struct_union)
{
	struct Denoted_Struct_Union *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Struct_Union));
	ret->denotation=DT_Struct_Union_Tag;
	ret->struct_union=struct_union;

	wonky_assert(is_valid_denoted_struct_union(ret));
	return (struct Denoted*)ret;
}
struct Denoted* get_denotation_prototype(struct Program *program)
{
	struct Denotation_Prototype *ret;
	ret=wonky_malloc(sizeof(struct Denotation_Prototype));
	ret->denotation=DT_Prototype;
	ret->type=NULL;
	ret->node=program->types;
	ret->storage_class=SCS_NONE;
	ret->specifier=TS_NONE;
	ret->constraint=TC_NONE;
	ret->sign=TSIGN_NONE;
	ret->function_specifier=FS_None;
	ret->struct_union=NULL;
	ret->enumerator=NULL;
	ret->size=0;
	ret->is_const=ret->is_volatile=0;

	wonky_assert(is_valid_denoted_prototype(ret));
	return (struct Denoted*)ret;
}
struct Denoted* extract_denoted(struct Denoted_Base *base,struct Denotation_Prototype *prototype,_Bool allow_abstract)
{
	if(base->type->specifier==TS_FUNC)
	{
		if(base->id==NULL && !allow_abstract)
		{
			return get_denoted_error(get_denoted_function(NULL,((struct Type_Function*)base->type)->return_type,prototype->function_specifier));
		}else
		{
			struct Denoted_Function *hold_denoted_function;
			hold_denoted_function=(struct Denoted_Function*)get_denoted_function(base->id,base->type,prototype->function_specifier);
			/*hack*/
			switch(prototype->storage_class)
			{
				case SCS_NONE:
					hold_denoted_function->linkage=LINKAGE_NONE;
					break;
				case SCS_EXTERN:
					hold_denoted_function->linkage=LINKAGE_EXTERNAL;
					break;
				case SCS_STATIC:
					hold_denoted_function->linkage=LINKAGE_INTERNAL;
					break;

			}
			return (struct Denoted*)hold_denoted_function;
		}
	}else if(prototype->storage_class==SCS_TYPEDEF)
	{
		if(base->id==NULL && !allow_abstract)
		{
			return get_denoted_error(get_denoted_typedef(base));
		}else
		{
			return get_denoted_typedef(base);
		}
	}else
	{
		if(base->id==NULL && !allow_abstract)
		{
			return get_denoted_error(get_denoted_object(base->id,prototype->storage_class,base->type,NULL));
		}else
		{
			return get_denoted_object(base->id,prototype->storage_class,base->type,NULL);
		}
	}
}

struct Denoted* get_denoted_statement(struct identifier *id,struct AST *statement,struct Denoted_Object *previous_denoted_object)
{
	struct Denoted_Statement *ret;
	ret=wonky_malloc(sizeof(struct Denoted_Statement));
	ret->denotation=DT_Statement;
	ret->label=id;
	ret->statement=statement;

	ret->previous_denoted_object=previous_denoted_object;
	ret->gotos_jumping_to_this_statement=wonky_malloc(sizeof(struct Queue));

	Queue_Init(ret->gotos_jumping_to_this_statement);

	wonky_assert(is_valid_denoted_statement(ret));
	return (struct Denoted*)ret;
}
void delete_denoted(struct Denoted *denoted)
{
	switch(denoted->denotation)
	{
		case DT_Statement:
			delete_denoted_statement((struct Denoted_Statement*)denoted);
			break;
		case DT_Object:
			delete_denoted_object((struct Denoted_Object*)denoted);
			break;
		case DT_Typedef:
			delete_denoted_typedef((struct Denoted_Type*)denoted);
			break;
		case DT_Function:
			delete_denoted_function((struct Denoted_Function*)denoted);
			break;
		case DT_Enum:
			delete_denoted_enum((struct Denoted_Enum*)denoted);
			break;
		case DT_Enum_Constant:
			delete_denoted_enum_constant((struct Denoted_Enum_Const*)denoted);
			break;
		case DT_Struct_Union_Tag:
			delete_denoted_struct_union((struct Denoted_Struct_Union*)denoted);
			break;
		case DT_Error:
			delete_denoted_error((struct Denoted_Error*)denoted);
			break;
		case DT_Prototype:
		default:
			wonky_assert(SHOULD_NOT_REACH_HERE);
	}
}
void delete_denoted_error(struct Denoted_Error *error)
{
	if(error->error!=NULL)
		delete_denoted(error->error);
	wonky_free(error);
}
void delete_denoted_function(struct Denoted_Function *function)
{
	if(function->id!=NULL)
		wonky_free(function->id);
	wonky_free(function);
}
void delete_denoted_object(struct Denoted_Object *object)
{
	if(object->id!=NULL)
		wonky_free(object->id);
	if(object->object!=NULL)
		delete_object(object->object);
	wonky_free(object);
}
void delete_denoted_typedef(struct Denoted_Type *typedefed)
{
	if(typedefed->id!=NULL)
		wonky_free(typedefed->id);
	wonky_free(typedefed);
}
void delete_denoted_enum(struct Denoted_Enum *enumeration)
{
	if(enumeration->enumeration!=NULL)
		delete_enum(enumeration->enumeration);
	wonky_free(enumeration);
}
void delete_denoted_enum_constant(struct Denoted_Enum_Const *enum_const)
{
	if(enum_const->id!=NULL)
		wonky_free(enum_const->id);
	if(enum_const->expression!=NULL)
		delete_ast(enum_const->expression);
	wonky_free(enum_const);
}
void delete_denoted_struct_union(struct Denoted_Struct_Union *su)
{
	if(su->struct_union!=NULL)
		delete_struct_union(su->struct_union);
	wonky_free(su);
}
void delete_denoted_prototype(struct Denotation_Prototype *prototype)
{
	wonky_free(prototype);
}
void delete_denoted_base(struct Denoted_Base *base)
{
	wonky_free(base);
}
void delete_denoted_statement(struct Denoted_Statement *statement)
{
	if(statement->label) wonky_free(statement->label);
	if(statement->statement) delete_ast(statement->statement);
	if(statement->gotos_jumping_to_this_statement)
	{
		while(statement->gotos_jumping_to_this_statement->size>0)
			Queue_Pop(statement->gotos_jumping_to_this_statement);
	}
	wonky_free(statement->gotos_jumping_to_this_statement);
	wonky_free(statement);
}
void delete_denoted_wrapper(void *denoted)
{
	delete_denoted(denoted);
}
void delete_denoted_with_no_linkage_wrapper(void *denoted)
{
	if( ((struct Denoted*)denoted)->denotation == DT_Object )
	{
		if( AS_DENOTED_OBJECT_PTR(denoted)->linkage!=LINKAGE_NONE )
			return;
	}else if( ((struct Denoted*)denoted)->denotation == DT_Function )
	{
		if( AS_DENOTED_FUNCTION(denoted)->linkage!=LINKAGE_NONE )
			return;
	}
	delete_denoted(denoted);
}



_Bool denoted_statement_is_declared(struct Denoted_Statement *statement)
{
	return statement->statement!=NULL;	
}

#endif