-
Notifications
You must be signed in to change notification settings - Fork 0
/
symboltable.c
104 lines (91 loc) · 1.88 KB
/
symboltable.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
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "symboltable.h"
#include "typedefs.h"
#define HASHSIZE 51
typedef struct symbol_entry *symbol_entry;
typedef enum { GATE, OUTPUT } type;
typedef union { logic_gate gate; logic_output output; } entry;
struct symbol_entry {
symbol_entry next;
char *label;
entry e;
type t;
};
symbol_entry SYMTAB[HASHSIZE];
/**
* @brief Hashes a key for the symbol table
*
* @param s
* @return uint64_t
*/
static uint64_t hash(char *s) {
uint64_t hash;
for (hash = 0; *s != '\0'; s++) {
hash = *s + 31 * hash;
}
return hash % HASHSIZE;
}
/**
* @brief Looks up an entry in the symbol table
*
* @param label
* @return logic_gate
*/
logic_gate lookup(char *label) {
symbol_entry se;
for (se = SYMTAB[hash(label)]; se != NULL; se = se->next) {
if (strcmp(label, se->label) == 0) {
assert(se->t == GATE);
return se->e.gate;
}
}
return NULL;
}
/**
* @brief Adds an entry to the symbol table
*
* @param gate
* @param label
*/
void add(logic_gate gate, char *label) {
assert(lookup(label) == NULL);
symbol_entry se = malloc(sizeof(struct symbol_entry));
assert(se != NULL);
se->label = strdup(label);
assert(se->label != NULL);
uint64_t h = hash(label);
se->next = SYMTAB[h];
se->t = GATE;
se->e.gate = gate;
SYMTAB[h] = se;
}
/**
* @brief Frees a single symbol table entry
*
* @param se
*/
static void free_symbol_entry(symbol_entry se) {
if (se != NULL) {
free_symbol_entry(se->next);
free(se->label);
if (se->t == GATE) {
se->e.gate = NULL;
} else {
se->e.output = NULL;
}
free(se);
}
}
/**
* @brief Frees memory allocated for symbol table
* @note Does not free logic gates as these will be reused
*
*/
void free_symbol_table() {
for (int i = 0; i < HASHSIZE; i++) {
free_symbol_entry(SYMTAB[i]);
}
}