From a4acd734f2064a6876849652e7f896ecade6497a Mon Sep 17 00:00:00 2001 From: "jordan@hack_attack" Date: Thu, 29 Sep 2016 13:31:59 -0700 Subject: [PATCH] forgot to commit ir.c --- src/apc/ir.c | 398 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 src/apc/ir.c diff --git a/src/apc/ir.c b/src/apc/ir.c new file mode 100644 index 0000000..1d56bd1 --- /dev/null +++ b/src/apc/ir.c @@ -0,0 +1,398 @@ +/*!@file + \brief IR Memory Implementation + \details Intermediary memory management + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +#include +#include +#include //uint64_t +#include //memmove +#include //malloc +#include + + +void +ir_init(void); +void +malloc_cdat(void); + + + +/* The initalization function of the IR. Mallocs the + first c/v/odat and the first links and refs and + inits the cdat_stack */ +void +ir_init() +{ + + /* Init root cdat and stack */ + char root[4] = "root"; + + cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof(struct cdat) ); + cdat_buf[num_cdats]->idx = 0; + memmove(cdat_buf[num_cdats]->name, root, 4); + + cdat_stackp = cdat_stack; + *cdat_stackp = cdat_buf[num_cdats++]; + +} + +//TODO: FREE MEMORY! +void +malloc_cdat() +{ + if(curr_max_cdats <= num_cdats) + { if( (realloc((void*) cdat_buf, PTRS_IN_PAGE * 4)) == NULL) + perror("realloc cdat_buf failed"); + curr_max_cdats += PTRS_IN_PAGE; + if( (realloc( (void*) cdat_stack, PTRS_IN_PAGE * 4)) == NULL) //increase cdat_stack also + perror("realloc cdat_stack failed"); + } + if( (cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof (struct cdat)) ) == NULL ) + perror("malloc cdat failed"); + + +} + +/* Dynamically allocate memory for a class data structure, + or cdat, after a class has been identified in a grammar. + We also create a stack of class pointers so that + we can access the cdat during processing of that + cdats sets and elements, a requirement because the + nature of recursive classes prevents us from accessing + the cdat based on the previous index into cdat_buf, + which is a list of all allocated cdats*/ +void +push_cdat +( char* name +) +{ + malloc_cdat(); + + memmove(cdat_buf[num_cdats]->name, name, 32); + cdat_buf[num_cdats]->idx = num_cdats; + + /* Set the cdat as a class of the previous cdat */ + (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes++] = cdat_buf[num_cdats]; + + /* Push the cdat onto the cdat_stack */ + *++cdat_stackp = cdat_buf[num_cdats++]; + +} + +void +pop_cdat +() +{ + *cdat_stackp = NULL; + cdat_stackp--; +} + +/* Called in the reduction of a set. While both odats (eles and sets) + have identical label terminals, we are unable to give a single grammatical rule + for both due to how we allocate odats in the odat buf. Due to the + nature of bottom up parsing, all the elements will be inserted into the + odat_buf first, and then the set that contains these element is inserted. Since + the sets label comes before the element list in the grammar, we would be giving an element + a set label in its respective odat, which would then be replaced by the + elements label. Instead, we store the label in the sets representation inside + CURR_CDAT and after we are done parsing the element_list and know that the CURR_ODAT + is the set, we populate the sets label members in CURR_ODAT with the values we stored + previously in CURR_CDAT. */ + +void +insert_set_label +( char* name, + uint64_t ref_id +) +{ + struct set* curr_set; + + curr_set = curr_set(); + memmove(curr_set.name,name,32); + curr_set.ref_id = ref_id; + +} +void +insert_set_olink +( uint64_t ref_id +) +{ + struct set* curr_set; + struct cdat* curr_cdat; + struct link* curr_link; + + curr_set = curr_set(); + curr_cdat = curr_cdat(); + curr_link = alloc_link(); + + curr_set.cdat_idx = curr_cdat->idx; + curr_set.ref_id = ref_id; /* Will be resolved to offset + when link is processed */ + curr_link->type = 1; + curr_link->link_t.olink.ref_id = ref_id; + curr_link->cdat_idx = curr_cdat->idx; + curr_link->set_idx = curr_cdat->num_sets++; + curr_link->ele_idx = -1; + +} + +void +insert_set_vlink +( uint64_t ref_id, + char* anim_name +) +{ + struct cdat* curr_cdat; + struct link* curr_link; + + curr_cdat = curr_cdat(); + curr_link = alloc_link(); + + /* Insert vlink into link_stack so that it gets processed at + output time */ + curr_link->type = 2; + curr_link->cdat_idx = curr_cdat->idx; + curr_link->set_idx = curr_cdat->num_sets; + curr_link->link_t.vlink.ref_id = ref_id; + memmove(curr_link->link_t.vlink.anim_name, anim_name, 32); + +} + +/* Svlinks dont have animation names */ +void +insert_set_svlink +( uint64_t ref_id +) +{ + struct cdat* curr_cdat; + struct link* curr_link; + + curr_cdat = curr_cdat(); + curr_link = alloc_link(); + + /* Insert vlink into link_stack so that it gets processed at + output time */ + curr_link->type = 3; + curr_link->cdat_idx = curr_cdat->idx; + curr_link->set_idx = curr_cdat->num_sets; + curr_link->link_t.svlink.ref_id = ref_id; + +} + +/* At the point of reducing to a set, most of the + sets odat information has already been populated + during the reduction of its right hand side + non terminals (hitbox, root, quad_list). */ +void +insert_set +() +{ + struct odat* curr_odat; + struct cdat* curr_cdat; + struct ref* prev_ref; + struct ref* curr_ref; + + curr_odat = alloc_odat(); + curr_cdat = curr_cdat(); + curr_set = curr_set(); + prev_ref = prev_ref(); + curr_ref = alloc_ref(); + + ref_id = curr_set.ref_id; // ref_id set by insert_set_label(name, ref_id) + + curr_set.cdat_idx = curr_cdat->idx; + memmove(curr_odat->name, curr_set.name, 32); + curr_cdat.num_sets++; + + curr_odat->cdat_idx = curr_cdaat->idx; + curr_odat->refp = curr_ref; + + + curr_ref->lastref = prev_ref; + prev_ref->nextref = curr_ref; + curr_ref->odatp = curr_odat; + + + if(ref_id == -1) /* user did not define a ref_id so */ + { ref_id = ss_ref_id; + ss_ref_id++; + } + + curr_ref->ref_id = ref_id; + +} +/* Created as a seperate function, instead of setting the ODATS vdat_id and + calling inc_vdat() inside of insert_set(), to account for the set reduction + where a vdat is not created (o/v/svlinks). */ + +void +insert_vdat_id +() +{ + struct odat* curr_odat; + curr_odat = curr_odat(); + curr_odat->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks +} + +/* Populates both the odat name and ref_id + for element. */ +void +insert_ele_label +( char* name, + uint64_t ref_id +) +{ + struct ele* curr_ele; + + curr_ele = curr_ele(); + + memmove(curr_ele.name, name, 32); + curr_ele.ref_id = ref_id; +} + +void +insert_ele_olink +( uint64_t ref_id +) +{ + CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx; + CURR_CDAT->CURR_SET.CURR_ELE.ref_id = ref_id; /* Will be resolved to offset + when link is processed */ + CURR_LINK->type = 1; + CURR_LINK->link_t.olink.ref_id = ref_id; + CURR_LINK->cdat_idx = CURR_CDAT->idx; + CURR_LINK->set_idx = CURR_CDAT->num_sets++; + CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele++; + +} + +void +insert_ele_vlink +( uint64_t ref_id, + char* anim_name +) +{ + + /* Insert vlink into link_stack so that it gets processed at + output time */ + CURR_LINK->cdat_idx = CURR_CDAT->idx; + CURR_LINK->type = 2; + CURR_LINK->set_idx = CURR_CDAT->num_sets; + CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele; + CURR_LINK->link_t.vlink.ref_id = ref_id; + memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32); + +} + +void +insert_ele_svlink +( uint64_t ref_id +) +{ + + CURR_LINK->cdat_idx = CURR_CDAT->idx; + CURR_LINK->type = 3; + CURR_LINK->set_idx = CURR_CDAT->num_sets; + CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele; + CURR_LINK->link_t.svlink.ref_id = ref_id; + + +} + +//Insert element into odat_buf and cdatpages +void +insert_ele() +{ + uint64_t ref_id; + + ref_id = CURR_CDAT->CURR_SET.CURR_ELE.ref_id; + + CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx; + memmove(CURR_ODAT->name,CURR_CDAT->CURR_SET.CURR_ELE.name, 32); + CURR_CDAT->CURR_SET.num_ele++; + + CURR_ODAT->cdat_idx = CURR_CDAT->idx; + CURR_ODAT->refp = CURR_REF; + + if(ref_id == -1) /* user did not define a ref_id so */ + { ref_id = ss_ref_id; + ss_ref_id++; + } + + CURR_REF->ref_id = ref_id; + + inc_odat(); + inc_ref(); + +} + +void +insert_framesheet +( char direction, + char* name, + uint64_t ref_id, + int height , + int width, + int num_frames +) +{ + CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].height = height; + CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].width = width; + CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames = num_frames; + CURR_VDAT->num_models++; +} + +void +insert_quad +( int x, + int y, + int z, + uint64_t ref_id +) +#define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads]) +{ + CURR_QUAD.x = x; + CURR_QUAD.y = y; + CURR_QUAD.z = z; + CURR_QUAD.ref_id = ref_id; + CURR_ODAT->num_quads++; +} + +/* Inserting the hitbox into the set + odat. Elements that don't have + a hitbox will use the sets root. */ +void +insert_hitbox +( int hitbox +) +{ + CURR_ODAT->hitbox = hitbox; +} + +/* Inserting the root into the set + odat. Elements that don't have + a root will use the sets root. */ +void +insert_root +( int x, + int y, + int z +) +{ + + CURR_ODAT->root.x = x; + CURR_ODAT->root.y = y; + CURR_ODAT->root.z = z; +} + +void +insert_frame_pointer +( char direction, + void* frame +) +{ + CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].frames[CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames++] = frame; +} + -- 2.18.0