-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsymtab.c
More file actions
executable file
·131 lines (115 loc) · 3.4 KB
/
symtab.c
File metadata and controls
executable file
·131 lines (115 loc) · 3.4 KB
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
/* $Id: symtab.c,v 1.4 2024/07/26 12:44:46 leavens Exp $ */
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "symtab.h"
#include "utilities.h"
// For a data structure, we use an array (for now),
// although a hash table might be better...
// size is also the index of the next element to allocate
static int size;
// The data structure is such that the first size entries contain actual data
static id_attrs_assoc entries[MAX_SYMTAB_SIZE];
// The symbol table's invariant
void symtab_okay()
{
assert(0 <= size);
assert(size < MAX_SYMTAB_SIZE);
for (int i = size; i < MAX_SYMTAB_SIZE; i++) {
assert(entries[i].name == NULL);
}
}
// initialize the symbol table
void symtab_initialize()
{
size = 0; // no data yet
id_attrs_assoc none;
none.name = NULL;
none.file_loc = NULL;
none.addr = 0;
for (int i = 0; i < MAX_SYMTAB_SIZE; i++) {
entries[i] = none;
}
symtab_okay();
}
// Return the number of mappings in this symbol table
unsigned int symtab_size() { return size; }
// Is this symbol table empty? (I.e., does it have not mappings?)
bool symtab_empty() { return size == 0; }
// Is this symbol table full? (I.e., can it not hold more mappings?)
// (i.e., is symtab_size() equal to MAX_SYMTAB_SIZE-1)?
bool symtab_full() { return size >= MAX_SYMTAB_SIZE; }
// Is the given name associated with some attributes?
bool symtab_defined(const char *name)
{
id_attrs_assoc *v = symtab_lookup(name);
return v != NULL;
}
// Requires: !symtab_full
// Requires: !symtab_defined(attrs.name)
// Remember the given attributes (i.e., an association from attrs.name
// to the other parts of attrs)
void symtab_insert(id_attrs_assoc attrs)
{
if (symtab_full()) {
bail_with_error("The symtab is full!");
}
entries[size++] = attrs;
}
// if name == NULL or if name is not defined, return -1
// if name is defined in the table, return its index
static int find_index(const char *name)
{
if (name == NULL) {
return -1;
}
for (int i = 0; i < size; i++) {
if (strcmp(entries[i].name, name) == 0) {
return i;
}
}
return -1;
}
// Return (a pointer to) the attributes of the given name
// or NULL if there is no association for that name.
id_attrs_assoc *symtab_lookup(const char *name)
{
int i = find_index(name);
if (0 <= i) {
return &entries[i];
} else {
return NULL;
}
}
// iteration helpers
// iterations use an external key which is a name
// Start an iteration by returning the first name in the symbol table,
// return NULL if symtab_empty()
const char *symtab_first_name()
{
if (symtab_empty()) {
return NULL;
}
assert(0 < size);
return entries[0].name;
}
// Are there more names defined in the symbol table after the given one?
// This returns false if name is NULL, if name is not defined,
// or if there are no more names following name in the symbol table
bool symtab_more_after(const char *name)
{
int i = find_index(name);
return (0 <= i && i < size);
}
// Requires: symtab_more_after(name);
// Return the next name defined in the symbol table after the given one,
// but return NULL if there are no more names
const char *symtab_next_name(const char *name)
{
int i = find_index(name);
if (i < 0 || i >= size) {
return NULL;
} else {
return entries[i+1].name;
}
}