This repository has been archived by the owner on Oct 22, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsymtab.c
103 lines (82 loc) · 2.24 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
#include <stdlib.h>
#include <string.h>
#include "symtab.h"
// the symbol table
symrec *symtab = NULL;
// prototypes for local functions
static void put(symrec *); // add a symbol to the table
static void del(symrec *); // delete a symbol from the table
static void free_rec(symrec *); // completely free a record in the symbol table
/*
* Perform a lookup in the symbol table for a symbol with "name"
* If the node exists, return it. Otherwise, create a new node
* in the symbol table for the specified name and return it
*/
symrec *lookup(char *name) {
symrec *sym;
// get the symbol if it already exists
for (sym = symtab; sym != NULL; sym = sym->next) {
if (strcmp(sym->name, name) == 0)
return sym;
}
// make the symbol if it doesn't exist
sym = malloc(sizeof(symrec));
memset(sym, 0, sizeof(symrec));
sym->name = (char *) malloc(strlen(name) + 1);
strcpy(sym->name, name);
put(sym);
return sym;
}
// build an empty argument list
// TODO remove this
func_arglist *make_empty_arglist() {
func_arglist *list = malloc(sizeof(func_arglist));
memset(list, 0, sizeof(func_arglist));
list->name = NULL;
list->arg = VOID;
list->next = NULL;
return list;
}
// add a node to the symbol table in O(1)
static void put(symrec *sym) {
sym->next = symtab;
symtab = sym;
}
// remove a node from the symbol table in O(1)
static void del(symrec *sym) {
symrec *next = sym->next;
// handle case of NULL pointer
if (!next) {
free_rec(sym);
sym = NULL;
}
// handle case of non-NULL pointer
sym->name = next->name;
sym->type = next->type;
sym->arglist = next->arglist;
sym->next = next->next;
free_rec(next);
}
// free a record in the symbol table, as well as all of its elements
static void free_rec(symrec *sym) {
free(sym->name); // free symbol name
// free symbol arglist (if it exists)
func_arglist *tmp;
for(func_arglist *al = sym->arglist; al != NULL;) {
tmp = al;
al = al->next;
free(tmp);
}
// don't free the pointer to the next struct, that's the responsibility of
// the caller to handle
free(sym);
}
// free the entire symbol table
void free_table() {
symrec *tmp;
for (symrec *sym = symtab; sym != NULL;) {
tmp = sym;
sym = sym->next;
free_rec(tmp);
}
}