-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdynamic_stack.c
140 lines (117 loc) · 3.05 KB
/
dynamic_stack.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "dynamic_stack.h"
#include "scanner.h"
const size_t INIT_SIZE = 512;
const double RESIZE_FACTOR = 0.7;
static dstack_t dstack_resize(dstack_t *const, size_t);
dstack_t dstack_ctor(void)
{
dstack_t stack;
stack.elem = calloc(sizeof(obj_t), INIT_SIZE);
if (stack.elem == NULL)
fprintf(stderr, "%s: Allocation of %zu elements for stack failed!\n", __func__, INIT_SIZE);
stack.size = INIT_SIZE;
stack.top = -1;
return stack;
}
dstack_t dstack_clear(dstack_t *const stack)
{
if (stack)
{
stack->top = -1;
}
return *stack;
}
bool dstack_empty(const dstack_t *const stack)
{
if (stack)
return stack->top == -1;
return true;
}
// HACK HACK what to do with 'o'?
obj_t *dstack_top(const dstack_t *const stack)
{
if (stack && stack->top >= 0)
return &stack->elem[stack->top];
return NULL;
}
void dstack_pop(dstack_t *const stack)
{
if (stack && stack->top >= 0)
--stack->top;
}
void dstack_push(dstack_t *const stack, obj_t c)
{
if (stack)
{
if (stack->top >= stack->size*RESIZE_FACTOR)
*stack = dstack_resize(stack, stack->size + stack->size);
stack->elem[++stack->top] = c;
}
}
static dstack_t dstack_resize(dstack_t *const stack, size_t sz)
{
obj_t *s = realloc(stack->elem, sz*sizeof(obj_t));
if (s != NULL)
{
stack->elem = s;
stack->size = sz;
}
else
fprintf(stderr, "%s: Reallocation of %zu bytes for stack failed!\n", __func__, sz);
return *stack;
}
dstack_t dstack_dtor(dstack_t *const stack)
{
if (stack)
{
if (stack->elem != NULL)
free(stack->elem);
stack->elem = NULL;
stack->size = 0;
stack->top = -1;
}
return *stack;
}
long dstack_elem_count(const dstack_t *const stack)
{
return (stack == NULL) ? 0 : stack->top+1;
}
bool dstack_replace(dstack_t *stack, long pos, obj_t *new, long num)
{
if (stack == NULL || new == NULL || pos < 0L || num <= 0L)
return false;
long len = dstack_elem_count(stack);
if (len && num && pos <= len)
{
if (len + num > (long)stack->size)
*stack = dstack_resize(stack, stack->size + stack->size);
for (long i = len; i >= pos; i--)
stack->elem[i+num] = stack->elem[i];
for (long i = 0; i != num; i++)
stack->elem[pos+i] = new[i];
stack->top += num;
return true;
}
return false;
}
bool dstack_add_handle_symbol(dstack_t *stack, unsigned symbol)
{
if (stack == NULL )
return false;
long end = stack->top;
for (; end != -1; end--)
{
if (stack->elem[end].type == symbol)
{
// we can hack maybe and add just '<' behind the symbol
expr_t left_sharp = {.type = '<'};
// insert one position behind the symbol in stack left sharp
dstack_replace(stack, end+1, &left_sharp, 1);
return true;
}
}
return false;
}