-
Notifications
You must be signed in to change notification settings - Fork 0
/
codegen_stack.c
181 lines (136 loc) · 4.38 KB
/
codegen_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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
* Project: Compiler for imperative programing language IFJ20
*
* File: codegen_stack.h
* Brief: Stack that holds up unique labels for jumps in if/else and for
*
* Authors: Hladký Tomáš xhladk15@stud.fit.vutbr.cz
* Kostolányi Adam xkosto04@stud.fit.vutbr.cz
* Makiš Jozef xmakis00@stud.fit.vutbr.cz
* Bartko Jakub xbartk07@stud.fit.vutbr.cz
*/
#include <stdio.h>
#include "error.h"
#include "codegen_stack.h"
jmp_label_stack_t *skip_labels_bottom = NULL;
jmp_label_stack_top_t *skip_labels_top = NULL;
jmp_label_stack_t *end_labels_bottom = NULL;
jmp_label_stack_top_t *end_labels_top = NULL;
jmp_label_stack_t *for_def_bottom = NULL;
jmp_label_stack_top_t *for_def_top = NULL;
void jmp_label_stack_init() {
// =================================
// If labels
// Skip labels
skip_labels_bottom = malloc(sizeof(jmp_label_stack_t));
if (skip_labels_bottom == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_init", "NULL pointer");
}
// Most bottom of stack must be always defined, its not used for data
skip_labels_bottom->value = 0;
skip_labels_bottom->next = NULL;
skip_labels_bottom->prev = NULL;
skip_labels_top = malloc(sizeof(jmp_label_stack_top_t));
if (skip_labels_top == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_init", "NULL pointer");
}
// Top points to bottom of stack
skip_labels_top->top = skip_labels_bottom;
// End labels
end_labels_bottom = malloc(sizeof(jmp_label_stack_t));
if (end_labels_bottom == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_init", "NULL pointer");
}
// Most bottom of stack must be always defined, its not used for data
end_labels_bottom->value = 0;
end_labels_bottom->next = NULL;
end_labels_bottom->prev = NULL;
end_labels_top = malloc(sizeof(jmp_label_stack_top_t));
if (end_labels_top == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_init", "NULL pointer");
}
// Top points to bottom of stack
end_labels_top->top = end_labels_bottom;
// =================================
// For labels
for_def_bottom = malloc(sizeof(jmp_label_stack_t));
if (for_def_bottom == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_init", "NULL pointer");
}
for_def_bottom->value = 0;
for_def_bottom->next = NULL;
for_def_bottom->prev = NULL;
for_def_top = malloc(sizeof(jmp_label_stack_top_t));
if (for_def_top == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_init", "NULL pointer");
}
for_def_top->top = for_def_bottom;
}
void jmp_label_stack_push(jmp_label_stack_top_t *top, int value) {
if (top == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_push", "NULL pointer");
}
jmp_label_stack_t *new_item = malloc(sizeof(jmp_label_stack_t));
if (new_item == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_push", "NULL pointer");
}
new_item->value = value;
new_item->next = NULL;
new_item->prev = top->top;
top->top->next = new_item;
top->top = new_item;
}
int jmp_label_stack_pop(jmp_label_stack_t *stack, jmp_label_stack_top_t *top) {
if (stack == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_pop", "NULL pointer");
}
if (top == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_pop", "NULL pointer");
}
if (top->top == stack) {
error(99, "codegen_stack.c", "jmp_label_stack_pop", "Cannot pop bottom");
}
jmp_label_stack_t *temp = top->top;
int pop_value = temp->value;
top->top = temp->prev;
top->top->next = NULL;
free(temp);
return pop_value;
}
int jmp_label_stack_top(jmp_label_stack_top_t *top) {
return top->top->value;
}
void jmp_label_stack_clear(jmp_label_stack_t *stack, jmp_label_stack_top_t *top) {
if (stack == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_push", "NULL pointer");
}
if (top == NULL) {
error(99, "codegen_stack.c", "jmp_label_stack_push", "NULL pointer");
}
while (stack != top->top) {
jmp_label_stack_pop(stack, top);
}
}
void jmp_label_stack_free_all() {
jmp_label_stack_free(skip_labels_bottom, skip_labels_top);
jmp_label_stack_free(end_labels_bottom, end_labels_top);
jmp_label_stack_free(for_def_bottom, for_def_top);
}
void jmp_label_stack_free(jmp_label_stack_t *stack, jmp_label_stack_top_t *top) {
if (stack == NULL && top == NULL) {
return;
}
if (stack != NULL && top != NULL) {
jmp_label_stack_clear(stack, top);
free(stack);
free(top);
}
else {
if (stack != NULL) {
free(stack);
}
if (top != NULL) {
free(top);
}
}
}