stk.c (3173B)
1 #include <stdlib.h> 2 #include <stdio.h> 3 4 #include "stk.h" 5 #include "var.h" 6 #include "helper.h" 7 8 stk_t* stk_new( void ) 9 { 10 stk_t* new = (stk_t*)malloc(sizeof(stk_t)); 11 M_ASSERT(new); 12 13 new->stack = stk_line_new(STACK_SIZE_LIMIT); 14 new->next = NULL; 15 16 return new; 17 } 18 19 stk_line* stk_line_new(size_t size) 20 { 21 ASSERT(size > 1, "stk_line_new\n"); 22 23 stk_line* new = (stk_line*)malloc(sizeof(stk_line)); 24 M_ASSERT(new); 25 26 int i; 27 for (i = 0; i < STACK_SIZE_LIMIT; i++) 28 { 29 new->data[i] = NULL; 30 } 31 32 new->size = size; 33 new->ptr = 0; 34 35 return new; 36 } 37 38 void stk_del(stk_t* stack) 39 { 40 N_ASSERT(stack, "stk_del"); 41 42 while (stack->next != NULL) 43 { 44 stk_poplevel(&stack); 45 } 46 47 stk_line_del(stack->stack); 48 49 free(stack); 50 } 51 52 void stk_line_del(stk_line* stack) 53 { 54 N_ASSERT(stack, "stk_line_del\n"); 55 56 int i; 57 for (i = 0; i < stack->size; i++) 58 { 59 if (stack->data[i] != NULL) 60 { 61 if (stack->data[i]->ownership < 0) 62 var_del(stack->data[i]); 63 } 64 } 65 66 free(stack); 67 } 68 69 /* Pushes a new stack level 70 * stk_t** - stack instances 71 */ 72 void stk_newlevel(stk_t** stack) 73 { 74 N_ASSERT(stack, "stk_newlevel\n"); 75 76 stk_t* new = stk_new(); 77 78 new->next = *stack; 79 80 *stack = new; 81 } 82 83 /* Pops a stack level 84 * stk_t* - stack instance 85 */ 86 void stk_poplevel(stk_t** stack) 87 { 88 N_ASSERT(stack, "stk_poplevel\n"); 89 90 if ((*stack)->next != NULL) 91 { 92 stk_t* tmp = (*stack)->next; 93 stk_line_del((*stack)->stack); 94 free(*stack); 95 *stack = tmp; 96 } 97 } 98 99 /* Pop the first element of the stack 100 * stk_t* - stack instance 101 */ 102 var_cont* stk_pop(stk_t* stack) 103 { 104 N_ASSERT(stack, "stk_pop\n"); 105 106 ASSERT(((stack->stack->ptr - 1) >= 0), "Stack Underflow\n"); 107 108 stack->stack->ptr = stack->stack->ptr - 1; 109 110 var_cont* rv = stack->stack->data[stack->stack->ptr]; 111 112 stack->stack->data[stack->stack->ptr] = NULL; 113 114 return rv; 115 } 116 117 /* Pushes var_cont* to the stack 118 * stk_t* - stack instance 119 * var_cont* - variable instance 120 */ 121 void stk_push(stk_t* stack, var_cont* data) 122 { 123 N_ASSERT(stack, "stk_push\n"); 124 N_ASSERT(data, "stk_push\n"); 125 126 ASSERT(((stack->stack->ptr + 1) < stack->stack->size), "STACK OVERFLOW!"); 127 128 stack->stack->data[stack->stack->ptr] = data; 129 130 stack->stack->ptr = stack->stack->ptr + 1; 131 } 132 133 /* Returns the data at location in the stack 134 * stk_line* - Stack line instance 135 * int - (integer + 1) < (STK_SIZE_LIMIT - stk_line->ptr) 136 */ 137 var_cont* stk_at(stk_t* stack, int n) 138 { 139 n = n + 1; 140 141 ASSERT(((stack->stack->ptr - n) >= 0), "Out of Bounds\n"); 142 143 var_cont* rv = stack->stack->data[stack->stack->ptr - n]; 144 145 return rv; 146 } 147 148 /* Rotates the top two elements of the stack 149 * i.e. [4, 3, 2, 1] -> [3, 4, 2, 1] 150 * ^ rot_top() 151 */ 152 void stk_rot_top(stk_t* stack) 153 { 154 N_ASSERT(stack, "stk_rot_top\n"); 155 156 var_cont* a; 157 var_cont* b; 158 159 a = stk_pop(stack); 160 b = stk_pop(stack); 161 stk_push(stack, a); 162 stk_push(stack, b); 163 } 164 165 /* Rotates the top three elements of the stack 166 * i.e. [4, 3, 2, 1] -> [2, 3, 4, 1] 167 * ^ rot_three() 168 */ 169 void stk_rot_three(stk_t* stack) 170 { 171 N_ASSERT(stack, "stk_rot_three\n"); 172 173 var_cont* a; 174 var_cont* b; 175 var_cont* c; 176 177 a = stk_pop(stack); 178 b = stk_pop(stack); 179 c = stk_pop(stack); 180 stk_push(stack, a); 181 stk_push(stack, b); 182 stk_push(stack, c); 183 }