// A utility function to create an empty queue struct Queue *createQueue() { struct Queue *q = (struct Queue*)malloc(sizeof(*q)); q->front = q->rear = NULL; return q; } int prev_type = 0; int curr_type = 0; void store_asm(struct Queue *q, int data, int type) { if (curr_type) prev_type = curr_type; curr_type = type; // Create a new LL node int t = 0; if (type == NODE_TYPE_NORMAL) t = STORE_NORMAL; else if ( type == NODE_TYPE_BRANCH_START || type == NODE_TYPE_BRANCH_END || type == NODE_TYPE_BRANCH_CHOICE_START || type == NODE_TYPE_BRANCH_CHOICE_END ) t = STORE_EMPTY; struct QNode *temp = newNode(data, t); temp->type = type; // If queue is empty, then new node is front and rear both if (q->rear == NULL) { temp->prev = NULL; q->front = q->rear = temp; return; } if (prev_type == NODE_TYPE_NORMAL) { if (type == NODE_TYPE_BRANCH_CHOICE_END) { // we reach a the end of a branch choice, add the address of the last reference, the pointer to the next node, to an array of pointers // last_ref = q->rear->ref; // printf("adding %d to the pointer list\n", last_ref); // ptr_add(&q->rear->ref); } } else if(type == NODE_TYPE_NORMAL && prev_type == NODE_TYPE_BRANCH_END) { // we reach a node and we where previously at a branch, set all referenced logged to the value of the current node reference, then we free the pointer list // printf("setting pointer list to %d\n", last_ref); // ptr_set(last_ref); // ptr_free(); } // Add the new node at the end of queue and change rear temp->prev = q->rear; // allocate a new array for our new item #if NODE_TYPE == LINKED if (!q->rear->next) { q->rear->next = malloc(sizeof(*q->rear->next)); } else { abort(); } // update rear->next to point to the new item q->rear->next = temp; // update rear to point to the rear->next, which is the item we just added, updating the pointer rear from our old item to our new item q->rear = q->rear->next; #elif NODE_TYPE == TREE struct QNode * p = q->rear; if (type == NODE_TYPE_BRANCH_CHOICE_START) { while(p) { if (p->type == NODE_TYPE_BRANCH_START) { puts("FOUND BRANCH START"); q->rear = p; break; } if (p->prev) p = p->prev; else p = NULL; } } // allocate a new array for our new item if (!q->rear->branch) { q->rear->branch_count = 1; q->rear->branch = malloc(sizeof(struct QNode)*q->rear->branch_count); } else { q->rear->branch_count++; q->rear->branch = realloc(q->rear->branch, sizeof(struct QNode)*q->rear->branch_count); } // update rear->next to point to the new item q->rear->branch[q->rear->branch_count-1] = temp; // update rear to point to the rear->next, which is the item we just added, updating the pointer rear from our old item to our new item q->rear = q->rear->branch[q->rear->branch_count-1]; #endif } void add(struct Queue **q, int data) { if (!(*q)) (*q) = createQueue(); store_asm((*q), data, NODE_TYPE_NORMAL); } void add_branch(struct Queue **q) { if (!(*q)) (*q) = createQueue(); store_asm((*q), 0, NODE_TYPE_BRANCH_START); global_indent++; } void end_branch(struct Queue **q) { global_indent--; if (!(*q)) (*q) = createQueue(); store_asm((*q), 0, NODE_TYPE_BRANCH_END); } void add_branch_choice(struct Queue **q) { if (!(*q)) (*q) = createQueue(); store_asm((*q), 0, NODE_TYPE_BRANCH_CHOICE_START); global_indent++; } void end_branch_choice(struct Queue **q) { global_indent--; if (!(*q)) (*q) = createQueue(); // if we have a branch_end, we need to go backwards in out linked list to the node that came before the branch start store_asm((*q), 0, NODE_TYPE_BRANCH_CHOICE_END); }