-
Notifications
You must be signed in to change notification settings - Fork 0
/
symtab.c
131 lines (117 loc) · 3.47 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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symtab.h"
#include "declarations.h"
#include "semantic.h"
void yyerror(char*s, ...);
/* hash function */
static unsigned symhash(char *sym){
unsigned int hash = 0 ;
unsigned c ;
while ( c = *sym++) hash = hash*9 ^ c ;
return hash ;
}
/* hashing with linear probing */
struct symbol *lookup(char* sym) {
struct symbol *sp = &symbol_table[symhash(sym)%SYM_TAB_SIZE];
int scount = SYM_TAB_SIZE ;
while (--scount>=0){
/* if the symbol already exists */
if(sp->name&& !strcmp(sp->name,sym)) {
yyerror("variable %s already declared \n",sym);
}
/* if there is an empty slot */
if(!sp->name){
sp->name = strdup(sym);
sp->value = 0 ;
sp->func = NULL ;
sp->syms = NULL ;
return sp ;
}
/* otherwise increment pointer while checking that we did not arrive at the end */
if(++sp >= symbol_table+SYM_TAB_SIZE) sp = symbol_table ;
}
yyerror("symbol table is full \n");
abort();
};
// TODO : this method is incomplete
/* assume there will be no collision */
struct symbol* exists(char* sym) {
struct symbol *sp = &symbol_table[symhash(sym)%SYM_TAB_SIZE];
/* if the symbol already exists */
if(sp->name&& !strcmp(sp->name,sym)) return sp ;
yyerror("use of undeclared variable\n",sym);
return NULL ;
};
/* should only be called after checking that the symbol does not exist already */
struct symbol *insert(char *sym ) {
/* assume there will be no collision */
struct symbol *sp = &symbol_table[symhash(sym)%SYM_TAB_SIZE];
int scount = SYM_TAB_SIZE ;
while (--scount>=0){
/* if the symbol already exists */
if(sp->name&& !strcmp(sp->name,sym)) exit(1) ;
/* if there is an empty slot */
if(!sp->name){
sp->name = strdup(sym);
sp->value = 0 ;
sp->func = NULL ;
sp->syms = NULL ;
return sp ;
}
/* otherwise increment pointer while checking that we did not arrive at the end */
if(++sp >= symbol_table+SYM_TAB_SIZE) sp = symbol_table ;
}
yyerror("symbol table is full \n");
abort();
}
struct symlist *newsymlist(struct symbol *sym, struct symlist *next){
struct symlist *sl = malloc(sizeof(struct symlist));
if(!sl) {
yyerror("out of space");
exit(0);
}
sl->sym = sym;
sl->next = next;
return sl;
}
/* free a list of symbols */
void symlistfree(struct symlist *sl) {
struct symlist *nsl;
while(sl) {
nsl = sl->next;
free(sl);
sl = nsl;
}
}
void def_func(struct symbol *name,struct symlist *syms,struct ast *stmts){
if(name->func) treefree(name->func);
if (name->syms) symlistfree(name->syms);
name->func = stmts ;
name->syms = syms ;
}
struct symbol *new_symbol(char *name){
struct symbol *s = malloc(sizeof(struct symbol));
if(!s){
printf("out of space");
exit(1);
}
s->name = strdup(name) ;
s->func = NULL ;
s->syms = NULL ;
s->value = 0.0f ;
return s ;
}
void print_symtab(){
printf("\n*****************************************");
printf("\n SYMBOL TABLE ");
printf("\n*****************************************\n");
for (int i = 0; i < SYM_TAB_SIZE; i++) {
if (symbol_table[i].name)
{
printf("%s ",symbol_table[i].name) ;
}
}
printf("\n*****************************************\n");
}