#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