-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsymtable.c
151 lines (135 loc) · 4.62 KB
/
symtable.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
/* Symbol Table --linked list
Used for Compilers class
Modified Spring 2015 to allow for name to pointed to by symtable, instead of copied, since the name is copied
into the heap
Modified to have levels. A level 0 means global variable, other levels means in range of the function. We
start out our offsets at 0 (from stack pointer) for level 1,,,when we enter a functional declaration.
We increment offset each time we insert a new variable. A variable is considered to be valid if it is found in
the symbol table at our level or lesser level. If at 0, then it is global.
We return a pointer to the symbol table when a variable matches our creteria.
We add a routine to remove variables at our level and above.
*/
#include <string.h>
#include <stdlib.h>
#include "symtable.h"
#include "ast.h"
int GTEMP = 0;
struct SymbTab *first; /* Global pointer in the SymbTab */
char *createTemp(){
char hold[100];
char *s;
sprintf(hold,"_T%d",GTEMP++);
s = strdup(hold);
return (s);
}
/* Simple Insert into the symbol table with the size, type level that the name is being inserted into */
struct SymbTab *Insert(char *name, enum SystemType mytype, int isafunc, int level, int mysize, int offset, ASTnode *fparms){
struct SymbTab *n;
n = Search(name,level, 0);
if(n != NULL){
printf("\n\tThe name %s exists at level %d already in the symbol table\n\tDuplicate can.t be inserted",name, level);
return (NULL);
}
else{
struct SymbTab *p;
p = malloc(sizeof(struct SymbTab));
p ->name = name;
p ->offset = offset; /* assign the offset */
p ->level = level; /* assign the level */
p ->mysize = mysize; /* assign the size */
p ->Type = mytype; /* assign the Type */
p ->myOperator = NULLType;
p ->IsAFunc = isafunc; /* assign the Function */
p ->fparms = fparms; /* assign the Function */
p ->next = NULL;
/* Check on how many elements we have in the symbol table */
if(first == NULL){
first = p;
}
else{
p ->next = first;
first = p;
}
return (p);
}
printf("\n\tLabel inserted\n");
}
/* print out a single symbol table entry -- for debugging */
void PrintSym(struct SymbTab *s){
printf("\t%s\t\t%d\t\t%d\n", s ->name, s ->offset, s ->level);
}
/* General display to see what is our symbol table */
void Display(){
int i;
struct SymbTab *p;
p = first;
printf("\n\tLABEL\t\tOffset \t LEVEL\n");
while (p != NULL)
{
PrintSym(p);
p = p ->next;
}
}
/* Search for a symbol name at level or below. We have to do multiple passes into the symbol table because we have to find
the name closest to us
If recur is non-zero, then we look through all of the levels, otherwise, only our level
We return a pointer to a SymbolTab structure so that we can use other functions/methods to get the attributes */
struct SymbTab *Search(char name[], int level, int recur){
int i,flag = 0;
struct SymbTab *p;
/* for each level, try to find our symbol */
while (level >= 0){
p = first;
while (p != NULL){
if((strcmp(p ->name,name) == 0) && (p ->level == level))
return p;
p = p->next;
}
if (recur == 0) return (NULL); /* we did not find it at our level */
level--; /* check the next level up */
}
return NULL; /* did not find it, return 0 */
}
/* Remove all enteries that have the indicated level
We need to take care about updating p ->first pointer into the linked list when we are deleting edge elements */
int Delete(int level){
struct SymbTab *p,*f = NULL; /* we follow with pointer f */
int SIZE = 0;
p = first;
/* cruise through the list */
while (p != NULL){
/* do we match? */
/* if it is the p ->first in the list we have to update p ->first, we know this by f being NULL */
if (p ->level >= level ){
SIZE += p ->mysize;
if (f == NULL)
first = p ->next;
/* not the p ->first element */
else{
f ->next = p ->next;
}
p = p ->next;
}
else{
/* update follow pointer, move the p pointer */
f = p;
p = p ->next;
}
}
return(SIZE);
}
int compareFormula(ASTnode *fparms, ASTnode *args){
if ((fparms == NULL) && (args == NULL)) {
return 1;
}
if ((fparms == NULL)) {
return 0;
}
if ((args == NULL)) {
return 0;
}
if ((fparms ->mytype == args ->mytype)) {
return (compareFormula(fparms ->next, args ->next));
}
return 0;
}