diff --git a/Makefile b/Makefile index db60e84..c567b36 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ endif # debug and release flags -DEBUG_CFLAGS=-O0 -Og -ggdb3 ${WARNINGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined \ +DEBUG_CFLAGS=-Og -ggdb3 ${WARNINGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined \ -fno-sanitize-recover=all -fstack-protector-strong -fstack-clash-protection -fno-common ${ADD_DBG_FLAGS} \ -DCHECK_TYCHE_BUGS=1 DEBUG_LDFLAGS=-fsanitize=address -fsanitize=undefined @@ -45,7 +45,7 @@ endif RELEASE_CFLAGS=-O3 -flto=auto -march=native -mtune=native -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong RELEASE_LDFLAGS=-flto=auto -CFLAGS+=-std=c99 -fPIC -fvisibility=hidden +CFLAGS+=-std=c99 -D_GNU_SOURCE -fPIC -fvisibility=hidden LDFLAGS+= @@ -102,4 +102,4 @@ libtyche.a: lib/vm.o libtyche.so.${VERSION}: LDFLAGS += ${RELEASE_LDFLAGS} libtyche.so.${VERSION}: lib/vm.o - $(CC) -shared -o $@ -Wl,-soname,libfoo.so.${VERSION_MAJOR} $^ ${LDFLAGS} \ No newline at end of file + $(CC) -shared -o $@ -Wl,-soname,libfoo.so.${VERSION_MAJOR} $^ ${LDFLAGS} diff --git a/lib/heap.c b/lib/heap.c index d943a3f..e6df048 100644 --- a/lib/heap.c +++ b/lib/heap.c @@ -1,23 +1,85 @@ #include "stack.c" #include +#include #include "khash.h" -typedef struct { -} HeapValue; -KHASH_MAP_INIT_INT(heap, HeapValue) +typedef int HEAP_KEY; + +typedef enum { + TH_STRING, TH_ARRAY, TH_TABLE, +} TYC_HEAP_TYPE; typedef struct { - khash_t(heap) *items; + TYC_HEAP_TYPE type; + union { + char* str; + // TODO - array and table + } value; +} HeapValue; +KHASH_MAP_INIT_INT(HEAP, HeapValue) + +typedef struct { + khash_t(HEAP) *items; } Heap; static void heap_init(Heap* h) { - h->items = kh_init(heap); + h->items = kh_init(HEAP); } static void heap_finalize(Heap* h) { - kh_destroy(heap, h->items); + for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) { + HeapValue value = kh_value(h->items, k); + switch (value.type) { + case TH_STRING: + free(value.value.str); + break; + case TH_ARRAY: + abort(); // not implemented yet + break; + case TH_TABLE: + abort(); // not implemented yet + break; + } + } + kh_destroy(HEAP, h->items); } + +static HEAP_KEY heap_add_string(Heap* h, const char* value) +{ + int ret; + khiter_t k; + HEAP_KEY key; + + do { + key = rand(); + k = kh_get(HEAP, h->items, key); + } while (k != kh_end(h->items)); + + k = kh_put(HEAP, h->items, key, &ret); + kh_value(h->items, k) = (HeapValue) { + .type = TH_STRING, + .value = { .str = strdup(value) } + }; + + return key; +} + +#include +static TYC_RESULT heap_get_string(Heap* h, HEAP_KEY key, const char** value) +{ + khiter_t k = kh_get(HEAP, h->items, key); + bool is_missing = (k == kh_end(h->items)); + if (is_missing) + return T_ERR_HEAP_KEY_NOT_FOUND; + *value = kh_value(h->items, k).value.str; + return T_OK; +} + +static size_t heap_size(Heap* h) +{ + return kh_size(h->items); +} \ No newline at end of file diff --git a/lib/tyche.h b/lib/tyche.h index ba94516..8052146 100644 --- a/lib/tyche.h +++ b/lib/tyche.h @@ -8,6 +8,7 @@ typedef enum { typedef enum { T_OK = 0, T_ERR_STACK_UNDERFLOW = -1, T_ERR_STACK_FP_UNDERFLOW = -2, T_ERR_STACK_ACCESS_OUT_OF_RANGE = -3, + T_ERR_HEAP_KEY_NOT_FOUND = -10, } TYC_RESULT; #endif //TYCHE_TYCHE_H diff --git a/test/tests.c b/test/tests.c index 72b3de5..2c11110 100644 --- a/test/tests.c +++ b/test/tests.c @@ -92,5 +92,20 @@ int main() stack_finalize(&s); } - // TODO - stack set + { + printf("### Heap\n"); + + Heap h; + heap_init(&h); + + HEAP_KEY key1 = heap_add_string(&h, "hello"); + HEAP_KEY key2 = heap_add_string(&h, "world"); + + const char* value; + assert(heap_get_string(&h, key1, &value) == T_OK); assert(strcmp(value, "hello") == 0); + assert(heap_get_string(&h, key2, &value) == T_OK); assert(strcmp(value, "world") == 0); + assert(heap_get_string(&h, 1000, &value) == T_ERR_HEAP_KEY_NOT_FOUND); + + heap_finalize(&h); + } } \ No newline at end of file