aboutsummaryrefslogtreecommitdiff
path: root/symtable.c
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2025-08-19 22:53:19 +0100
committerAryadev Chavali <aryadev@aryadevchavali.com>2025-08-19 22:53:19 +0100
commit78aa7d6fb3dfcf385886ffceb665eb9fa74a9c2a (patch)
treea0f552d619c79f0a2be7b309566f0b5cfb2c1277 /symtable.c
parentb87a0c473abd543b6e6d6e95faa6f783df23a285 (diff)
downloadalisp-78aa7d6fb3dfcf385886ffceb665eb9fa74a9c2a.tar.gz
alisp-78aa7d6fb3dfcf385886ffceb665eb9fa74a9c2a.tar.bz2
alisp-78aa7d6fb3dfcf385886ffceb665eb9fa74a9c2a.zip
Separate out implementation to make looking at code files easier
Diffstat (limited to 'symtable.c')
-rw-r--r--symtable.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/symtable.c b/symtable.c
new file mode 100644
index 0000000..a159b69
--- /dev/null
+++ b/symtable.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 2025 Aryadev Chavali
+
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the Unlicense for details.
+
+ * You may distribute and modify this code under the terms of the Unlicense,
+ * which you should have received a copy of along with this program. If not,
+ * please go to <https://unlicense.org/>.
+
+ * Created: 2025-08-19
+ * Description: Symbol Table implementation
+ */
+
+#include "./base.h"
+
+#include <malloc.h>
+#include <string.h>
+
+u64 djb2(sv_t string)
+{
+ u64 hash = 5381;
+ for (u64 i = 0; i < string.size; ++i)
+ hash = string.data[i] + (hash + (hash << 5));
+ return hash;
+}
+
+void sym_table_init(sym_table_t *table)
+{
+ table->capacity = MAX(table->capacity, SYM_TABLE_INIT_SIZE);
+ table->count = 0;
+ vec_make((void **)&table->entries, table->capacity * sizeof(*table->entries));
+}
+
+sv_t sym_table_find(sym_table_t *table, sv_t sv)
+{
+ // TODO: Deal with resizing this when table->count > table->size / 2
+ u64 index = djb2(sv) & (table->capacity - 1);
+
+ for (sv_t comp = table->entries[index]; comp.data; index += 1,
+ index = index & (table->capacity - 1), comp = table->entries[index])
+ // Is it present in the table?
+ if (sv.size == comp.size && strncmp(sv.data, comp.data, sv.size) == 0)
+ return comp;
+
+ // Otherwise we need to duplicate and make it permanently interned
+ sv_t newsv = sv_copy(sv);
+ table->entries[index] = newsv;
+ ++table->count;
+
+ return newsv;
+}
+
+void sym_table_cleanup(sym_table_t *table)
+{
+ for (u64 i = 0; i < table->capacity; ++i)
+ if (table->entries[i].data)
+ free(table->entries[i].data);
+ vec_free((void **)&table->entries);
+ memset(table, 0, sizeof(*table));
+}