commit fbfe5b87f9dcd82eca0a2df6971bac9dcaca62f9
parent 8f5f7a310b42fc1144b6696334a175c68a38cbb3
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date: Tue, 27 Feb 2024 13:58:10 -0300
Add interning library
Diffstat:
3 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/coding/interning.c b/coding/interning.c
@@ -0,0 +1,45 @@
+#include "interning.h"
+#include <stdbool.h>
+#include <assert.h>
+#include <string.h>
+
+static char **db = NULL;
+static size_t cap = 0;
+static size_t len = 0;
+static bool initialized = false;
+
+void
+initialize(void)
+{
+ cap = 1;
+ db = malloc(cap * sizeof(char*));
+ initialized = true;
+}
+
+symbol
+append(char *name)
+{
+ assert(initialized);
+ if (len == cap)
+ db = realloc(db, (cap *= 2)*sizeof(char*));
+ assert(db);
+ db[len] = name;
+ return len++;
+}
+
+symbol
+intern(char *name)
+{
+ assert(initialized);
+ for (size_t i = 0; i < len; i++)
+ if (strcmp(name, db[i]) == 0)
+ return i;
+ return append(name);
+}
+
+char*
+repr(symbol s)
+{
+ assert(initialized);
+ return db[s];
+}
diff --git a/coding/interning.h b/coding/interning.h
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+
+typedef size_t symbol;
+
+/* Guarantees:
+ - strcmp(repr(intern(s)), s) == 0
+ - intern(repr(s)) == s
+ */
+
+void initialize();
+symbol intern(char*);
+char* repr(symbol);
diff --git a/coding/interning.test.c b/coding/interning.test.c
@@ -0,0 +1,26 @@
+#include "interning.h"
+#include <stdbool.h>
+#include <assert.h>
+#include <string.h>
+
+bool
+test_repr_of_intern_is_iso()
+{
+ char *test = "abc";
+ return strcmp(repr(intern(test)), test) == 0;
+}
+
+bool
+test_intern_of_repr_is_id()
+{
+ char *test = "abc";
+ symbol s = intern(test);
+ return intern(repr(s)) == s;
+}
+
+int
+main() {
+ initialize();
+ assert(test_repr_of_intern_is_iso());
+ assert(test_intern_of_repr_is_id());
+}