commit e26850e8f35c3b20b02edfa9ffa5c9ed81f8a58a
parent fbfe5b87f9dcd82eca0a2df6971bac9dcaca62f9
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date: Tue, 27 Feb 2024 14:59:38 -0300
Add associative list library
Diffstat:
3 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/coding/assoc.c b/coding/assoc.c
@@ -0,0 +1,83 @@
+#include "assoc.h"
+
+struct cell {
+ symbol key;
+ void *value;
+ struct cell *next;
+};
+
+struct assoc {
+ struct cell *cells;
+};
+
+assoc*
+new_assoc(void)
+{
+ return calloc(1, sizeof(struct assoc));
+}
+
+struct cell*
+new_cell(symbol s, void *v)
+{
+ struct cell *c = malloc(sizeof(struct cell));
+ c->key = s;
+ c->value = v;
+ return c;
+}
+
+void
+set(struct cell *c, symbol s, void* v)
+{
+ if (c->key == s)
+ c->value = v;
+ else if (c->next == NULL)
+ c->next = new_cell(s, v);
+ else
+ set(c->next, s, v);
+}
+
+void
+assoc_set(assoc* a, symbol s, void* v)
+{
+ if (a->cells == NULL)
+ a->cells = new_cell(s, v);
+ else
+ set(a->cells, s, v);
+}
+
+void*
+get(struct cell *c, symbol s)
+{
+ if (c == NULL)
+ return NULL;
+ else if (c->key == s)
+ return c->value;
+ else if (c->next == NULL)
+ return NULL;
+ else
+ return get(c->next, s);
+}
+
+void*
+assoc_get(assoc* a, symbol s)
+{
+ return get(a->cells, s);
+}
+
+void
+free_cells(struct cell *c)
+{
+ if (c->next)
+ free_cells(c->next);
+ free(c);
+}
+
+void
+free_assoc(assoc *a)
+{
+ if (a->cells)
+ free_cells(a->cells);
+ free(a);
+}
+
+
diff --git a/coding/assoc.h b/coding/assoc.h
@@ -0,0 +1,12 @@
+#include "interning.h"
+
+typedef struct assoc assoc;
+
+/* Guarantees:
+ - assoc_set(s, p), assoc_get(s) == p;
+ */
+
+assoc* new_assoc(void);
+void* assoc_get(assoc*, symbol);
+void assoc_set(assoc*, symbol, void*);
+void free_assoc(assoc*);
diff --git a/coding/assoc.test.c b/coding/assoc.test.c
@@ -0,0 +1,26 @@
+#include <stdbool.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "interning.h"
+#include "assoc.h"
+
+bool
+test_get_after_set_is_id()
+{
+ symbol k = intern("k");
+
+ assoc *a = new_assoc();
+ assoc_set(a, k, (void*)123);
+ bool res = assoc_get(a, k) == (void*)123;
+ free_assoc(a);
+ return res;
+}
+
+int
+main()
+{
+ initialize();
+ assert(test_get_after_set_is_id());
+ return 0;
+}