-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSymbolTableHandler.c
154 lines (129 loc) · 3.84 KB
/
SymbolTableHandler.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
#include "declarationsHeader.h"
extern symPtr symTableHead;
extern struct keyWords keys[];
/*
* Adding the passed string to the symbol table.
*/
void addToSymTable(char *newSym, int *cnt, boolean definedInFile) {
symPtr ptr = symTableHead, newNode;
char lineCpy[LINE_SIZE];
static symPtr last;
if (symIsExtern(ptr, newSym))
return;
strcpy(lineCpy, line);
newNode = (symPtr) malloc(sizeof(symbol));
MEMORY_ERROR(newNode)
strcpy(newNode->symName, newSym);
symInitailzeSetting(newNode, cnt, definedInFile);;
extSymbolSetting(lineCpy, newSym, newNode);
insSymbolSetting(lineCpy, newNode);
if (symTableHead == NULL) {
symTableHead = newNode;
last = symTableHead;
} else {
last->next = newNode;
last = last->next;
}
}
boolean symIsExtern(symPtr ptr, char *newSym) {
while (ptr != NULL) {
if (strcmp(ptr->symName, newSym) == EQUAL) {
if (ptr->data == -1 && !ptr->definedInFile) {
ptr->isExt = TRUE;
return TRUE;
}
}
ptr = ptr->next;
}
return FALSE;
}
void insSymbolSetting(char *lineCpy, symPtr newNode) {
int i;
for (i = 0; i < ACTIONS_NUM; i++) {
if (strstr(lineCpy, keys[i].symbol)) {
newNode->inInsSen = TRUE;
}
}
}
void symInitailzeSetting(symPtr newNode, int *cnt, boolean definedInFile) {
newNode->data = cnt != NULL ? (*cnt) : -1;
newNode->definedInFile = definedInFile;
newNode->isExt = FALSE;
newNode->isEnt = FALSE;
newNode->next = NULL;
}
void extSymbolSetting(char *lineCpy, char *newSym, symPtr pSymbol) {
if (strstr(lineCpy, GUIDING_SENTENCE_EXTERN)) {
symIsIllegal(newSym);
pSymbol->isExt = TRUE;
}
}
/*
* After the first pass we update each symbol table to its correct address.
* */
void updateSymbolTable(int *IC) {
symPtr ptr = symTableHead;
for (; ptr != NULL; ptr = ptr->next) {
if (ptr->isExt != TRUE && ptr->inInsSen != TRUE)
ptr->data += (*IC);
}
}
/*
* Searching for errors withing the symbol table after the second pass.
*/
boolean errorsInSymTable() {
symPtr ptr = symTableHead;
const short ext = -1;
for (; ptr; ptr = ptr->next) {
if (ptr->data == ext && ptr->isExt != TRUE) {
printErrorWithComment(undef_symbol, ptr->symName);
return TRUE;
}
}
for (ptr = symTableHead; ptr; ptr = ptr->next) {
if (ptr->isEnt && ptr->isExt)
printErrorWithComment(symbol_is_ent_and_ext, ptr->symName);
}
return FALSE;
}
/*
* Updates lables that are being used during a command line.
*/
void updateLabelAddress(char *sym, int *CNT) {
symPtr p = symTableHead;
/*Relates only to labels in a instruction sentence.*/
/*After we know the right address we update it in the Symbol Table.*/
while (p != NULL) {
if (strcmp(p->symName, sym) == EQUAL) {
p->data = *CNT;
}
p = p->next;
}
}
/*
* Debugging func, prints the symbol table to the screen.
*/
void printSymTable() {
symPtr p = symTableHead;
fprintf(stdout, "\n--------------------------------------------------------------------\n");
fprintf(stdout, "Symbol\t| Address\t| isExternal\t| isInActionSen\t| isEnt\t\t|\n");
while (p) {
printf("'%s'\t| %d\t\t| %s\t\t| %s\t\t| %s\t\t|\n",
p->symName, p->data, p->isExt == 1 ? "yes" : "no", p->inInsSen == 1 ? "yes" : "no",
p->isEnt ? "yes" : "no");
p = p->next;
}
fprintf(stdout, "----------------------------------------------------------------------\n");
}
/*
* Frees the symbol table.
*/
void freeSymTable() {
symPtr ptr;
while (symTableHead != NULL) {
ptr = symTableHead;
symTableHead = symTableHead->next;
free(ptr);
}
symTableHead = NULL;
}