-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsymtab.c
226 lines (195 loc) · 5.92 KB
/
symtab.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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include "defs.h"
#include "symtab.h"
SYMBOL_ENTRY symbol_table[SYMBOL_TABLE_LENGTH];
int first_empty = 0;
unsigned no_type_array[10] = {0,0,0,0,0,0,0,0,0,0};
// Vraca indeks prvog sledeceg praznog elementa.
int get_next_empty_element(void) {
if(first_empty < SYMBOL_TABLE_LENGTH)
return first_empty++;
else {
err("Compiler error! Symbol table overflow!");
exit(EXIT_FAILURE);
}
}
// Vraca indeks poslednjeg zauzetog elementa.
int get_last_element(void) {
return first_empty-1;
}
// Ubacuje simbol sa datom vrstom simbola i tipom simbola
// i vraca indeks ubacenog elementa u tabeli simbola
// ili -1 u slucaju da nema slobodnog elementa u tabeli.
int insert_symbol(char *name, unsigned kind, unsigned type,
unsigned atr1, unsigned atr2[], unsigned pok){
int index = get_next_empty_element();
symbol_table[index].name = name;
symbol_table[index].kind = kind;
symbol_table[index].type = type;
symbol_table[index].atr1 = atr1;
for (int i = 0; i < 10; i++)
symbol_table[index].atr2[i] = atr2[i];
symbol_table[index].pok = pok;
return index;
}
// Ubacuje konstantu u tabelu simbola (ako vec ne postoji).
int insert_literal(char *str, unsigned type) {
int idx;
for(idx = first_empty - 1; idx > FUN_REG; idx--) {
if(strcmp(symbol_table[idx].name, str) == 0
&& symbol_table[idx].type == type)
return idx;
}
// provera opsega za konstante
long int num = atol(str);
if(((type==INT) && (num<INT_MIN || num>INT_MAX) )
|| ((type==BYTE) && (num< SCHAR_MIN || num> SCHAR_MAX)) )
err("literal out of range");
idx = insert_symbol(str, LIT, type, NO_ATR, no_type_array, NO_ATR);
return idx;
}
// Vraca indeks pronadjenog simbola ili vraca -1.
int lookup_symbol(char *name, unsigned kind) {
int i;
for(i = first_empty - 1; i > FUN_REG; i--) {
if(strcmp(symbol_table[i].name, name) == 0
&& symbol_table[i].kind & kind)
return i;
}
return -1;
}
void set_name(int index, char *name) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
symbol_table[index].name = name;
}
char *get_name(int index) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
return symbol_table[index].name;
return "?";
}
void set_kind(int index, unsigned kind) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
symbol_table[index].kind = kind;
}
unsigned get_kind(int index) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
return symbol_table[index].kind;
return NO_KIND;
}
void set_type(int index, unsigned type) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
symbol_table[index].type = type;
}
unsigned get_type(int index) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
return symbol_table[index].type;
return NO_TYPE;
}
void set_atr1(int index, unsigned atr1) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
symbol_table[index].atr1 = atr1;
}
unsigned get_atr1(int index) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
return symbol_table[index].atr1;
return NO_ATR;
}
void set_atr2(int index, int index2, unsigned type) {
printf("T:%dIND:%dTYPE:%d\n", index, index2, type);
if(index > -1 && index < SYMBOL_TABLE_LENGTH && index2 > -1 && index2 < 10)
symbol_table[index].atr2[index2] = type;
}
unsigned get_atr2(int index, int index2) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
return symbol_table[index].atr2[index2];
return NO_ATR;
}
void set_pok(int index, unsigned pok) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
symbol_table[index].pok = pok;
}
unsigned get_pok(int index) {
if(index > -1 && index < SYMBOL_TABLE_LENGTH)
return symbol_table[index].pok;
return NO_ATR;
}
// Brise elemente tabele od zadatog indeksa do kraja tabele
void clear_symbols(unsigned begin_index) {
int i;
if(begin_index == first_empty) //nema sta da se brise
return;
if(begin_index > first_empty) {
err("Compiler error! Wrong clear symbols argument");
exit(EXIT_FAILURE);
}
for(i = begin_index; i < first_empty; i++) {
if(symbol_table[i].name)
free(symbol_table[i].name);
symbol_table[i].name = 0;
symbol_table[i].kind = NO_KIND;
symbol_table[i].type = NO_TYPE;
symbol_table[i].atr1 = NO_ATR;
for (int j = 0; j < 10; j++)
symbol_table[i].atr2[j] = NO_TYPE ;
symbol_table[i].pok = NO_ATR; // maybe something else?
}
first_empty = begin_index;
}
// Brise sve elemente tabele simbola.
void clear_symtab(void) {
first_empty = SYMBOL_TABLE_LENGTH - 1;
clear_symbols(0);
}
// Ispisuje sve elemente tabele simbola.
void print_symtab(void) {
static const char *symbol_kinds[] = {
"NONE", "REG", "LIT", "FUN", "VAR", "PAR", "GLB" };
int i,j;
printf("\n\nSYMBOL TABLE\n");
printf("\n name kind type atr1 pok atr2");
printf("\n-- ---------------- -------- ---- ----- ----- ----------");
for(i = 0; i < first_empty; i++) {
printf("\n%2d %-19s %-4s %4d %4d %4d %4d,%d,%d,%d,%d,%d,%d,%d,%d,%d", i,
symbol_table[i].name,
symbol_kinds[(int)(logarithm2(symbol_table[i].kind))],
symbol_table[i].type,
symbol_table[i].atr1,
symbol_table[i].pok,
symbol_table[i].atr2[0],
symbol_table[i].atr2[1],
symbol_table[i].atr2[2],
symbol_table[i].atr2[3],
symbol_table[i].atr2[4],
symbol_table[i].atr2[5],
symbol_table[i].atr2[6],
symbol_table[i].atr2[7],
symbol_table[i].atr2[8],
symbol_table[i].atr2[9]);
}
printf("\n\n");
}
unsigned logarithm2(unsigned value) {
unsigned mask = 1;
int i = 0;
for(i = 0; i < 32; i++) {
if(value & mask)
return i;
mask <<= 1;
}
return 0; // ovo ne bi smelo; indeksiraj string "NONE"
}
// Inicijalizacija tabele simbola.
void init_symtab(void) {
clear_symtab();
int i = 0;
char s[4];
for(i = 0; i < 7; i++) { // MAX NUMBER OF REGISTERS r0-r6
sprintf(s, "r%d", i);
insert_symbol(strdup(s), REG, NO_TYPE, NO_ATR,no_type_array, NO_ATR);
}
}