summaryrefslogtreecommitdiff
path: root/src/symtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/symtab.c')
-rw-r--r--src/symtab.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/symtab.c b/src/symtab.c
new file mode 100644
index 0000000..0034480
--- /dev/null
+++ b/src/symtab.c
@@ -0,0 +1,55 @@
+#include "symtab.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "sv.h"
+
+void symtab_init(struct symbol_table *symtab)
+{
+ assert(symtab != NULL);
+ symtab->cap = 150;
+ symtab->count = 0;
+ symtab->entries = malloc(150);
+}
+
+void symtab_expand(struct symbol_table *symtab)
+{
+ assert(symtab != NULL);
+ size_t newcap = symtab->cap * 2;
+ void* newbuf = malloc(newcap);
+ memcpy(newbuf, symtab->entries, symtab->cap);
+ free(symtab->entries);
+ symtab->cap = newcap;
+ symtab->entries = newbuf;
+}
+
+void symtab_free(struct symbol_table *symtab)
+{
+ assert(symtab != NULL);
+ symtab->count = 0;
+ symtab->cap = 0;
+ free(symtab->entries);
+}
+
+struct symlookup_result symtab_lookup(struct symbol_table *symtab, struct string_view ent)
+{
+ for(size_t i = 0; i < symtab->count; i++) {
+ struct symbol_entry *syment = &symtab->entries[i];
+
+ if(ent.len != syment->name.len) continue;
+
+ if(strncmp(ent.buf, syment->name.buf, ent.len) == 0) {
+ return (struct symlookup_result){.ent = syment, .i = i};
+ }
+ }
+ return (struct symlookup_result){.ent = NULL, .i = 0};
+}
+
+size_t symtab_append(struct symbol_table *symtab, struct symbol_entry syment)
+{
+ if(symtab->count + 1 >= symtab->cap) symtab_expand(symtab);
+ symtab->entries[symtab->count++] = syment;
+ return symtab->count - 1;
+}