From 008f173f9b9e52ae41683939614239059c0d3b04 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 19 Oct 2021 18:21:25 +0200 Subject: Change string/symbol representation to use darray.h --- src/bootstrap/darray.h | 23 +++++++++++++++++++++++ src/bootstrap/gc.c | 12 ++---------- src/bootstrap/objects.c | 26 +++++++++++--------------- src/bootstrap/objects.h | 2 -- src/bootstrap/primitives.c | 2 +- 5 files changed, 37 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/bootstrap/darray.h b/src/bootstrap/darray.h index bb49cdd..db6234d 100644 --- a/src/bootstrap/darray.h +++ b/src/bootstrap/darray.h @@ -25,6 +25,10 @@ typedef struct ArrayHeader { // Return the last element of the array. Can be used to build stacks. #define array_pop(ARR) (ARR)[--array_head(ARR)->size] +// Insert N bytes from the SRC array into the ARR dynamic array. +#define array_insert(ARR, SRC, N) \ + ((ARR) = _array_insert(ARR, SRC, N, sizeof(*(ARR)))) + // Free the memory from the original allocated position. #define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0) @@ -52,4 +56,23 @@ _array_maybe_grow(void *arr, size_t type_size) { return arr; } +static inline +char * _array_insert(char *arr, const char *src, size_t n_bytes, size_t type_size) { + ArrayHeader *head = array_head(arr); + size_t new_size = n_bytes + head->size; + if (new_size >= head->cap * type_size) { + if (head->cap == 0) { + head->cap = 1; + } + while (new_size >= head->cap * type_size) { + head->cap *= 2; + } + head = realloc(head, head->cap * type_size + sizeof(ArrayHeader)); + } + arr = (char *)head + sizeof(ArrayHeader); + memcpy((arr + head->size), src, n_bytes); + head->size = new_size; + return arr; +} + #endif // BDL_DARRAY_H diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c index a72f718..48499ac 100644 --- a/src/bootstrap/gc.c +++ b/src/bootstrap/gc.c @@ -121,17 +121,9 @@ mark_and_sweep(void) { if (!obj->marked) { // Free heap allocated memory for this object if needed. if (obj->type == OBJ_TYPE_SYMBOL) { - if (obj->symbol != NULL) { - free(obj->symbol); - } - obj->symbol = NULL; - obj->symbol_n = 0; + array_free(obj->symbol); } else if (obj->type == OBJ_TYPE_STRING) { - if (obj->symbol != NULL) { - free(obj->string); - } - obj->string = NULL; - obj->string_n = 0; + array_free(obj->string); } gc.free_objects.buf[gc.free_objects.size++] = i; } diff --git a/src/bootstrap/objects.c b/src/bootstrap/objects.c index 359329b..3ca2e43 100644 --- a/src/bootstrap/objects.c +++ b/src/bootstrap/objects.c @@ -30,9 +30,9 @@ make_pair(Object *car, Object *cdr) { Object * make_symbol(StringView sv) { Object *obj = alloc_object(OBJ_TYPE_SYMBOL); - obj->symbol = malloc(sizeof(char) * sv.n); - memcpy(obj->symbol, sv.start, sv.n); - obj->symbol_n = sv.n; + obj->symbol = NULL; + array_init(obj->symbol, sv.n); + array_insert(obj->symbol, sv.start, sv.n); return obj; } @@ -40,20 +40,16 @@ Object * make_string(void) { Object *obj = alloc_object(OBJ_TYPE_STRING); obj->string = NULL; - obj->string_n = 0; + array_init(obj->string, 0); return obj; } void append_string(Object *obj, const StringView sv) { - assert(obj != NULL); - assert(obj->type == OBJ_TYPE_STRING); if (sv.n == 0) { return; } - obj->string = realloc(obj->string, (obj->string_n + sv.n) * sizeof(char)); - memcpy(obj->string + obj->string_n, sv.start, sv.n); - obj->string_n += sv.n; + array_insert(obj->string, sv.start, sv.n); } void @@ -87,10 +83,10 @@ display(Object *root) { printf("()"); } break; case OBJ_TYPE_STRING: { - printf("\"%.*s\"", (int)root->string_n, root->string); + printf("\"%.*s\"", (int)array_size(root->string), root->string); } break; case OBJ_TYPE_SYMBOL: { - printf(":%.*s", (int)root->symbol_n, root->symbol); + printf(":%.*s", (int)array_size(root->symbol), root->symbol); } break; case OBJ_TYPE_PAIR: { printf("("); @@ -118,20 +114,20 @@ obj_eq(Object *a, Object* b) { return a->fixnum == b->fixnum; } break; case OBJ_TYPE_STRING: { - if (a->string_n != b->string_n) { + if (array_size(a->string) != array_size(b->string)) { return false; } - for (size_t i = 0; i < a->string_n; i++) { + for (size_t i = 0; i < array_size(a->string); i++) { if (a->string[i] != b->string[i]) { return false; } } } break; case OBJ_TYPE_SYMBOL: { - if (a->symbol_n != b->symbol_n) { + if (array_size(a->symbol) != array_size(b->symbol)) { return false; } - for (size_t i = 0; i < a->symbol_n; i++) { + for (size_t i = 0; i < array_size(a->symbol); i++) { if (a->symbol[i] != b->symbol[i]) { return false; } diff --git a/src/bootstrap/objects.h b/src/bootstrap/objects.h index cba6f10..5968a44 100644 --- a/src/bootstrap/objects.h +++ b/src/bootstrap/objects.h @@ -27,7 +27,6 @@ typedef struct Object { // OBJ_TYPE_STRING struct { char *string; - size_t string_n; }; // OBJ_TYPE_PAIR @@ -39,7 +38,6 @@ typedef struct Object { // OBJ_TYPE_SYMBOL struct { char *symbol; - size_t symbol_n; }; // OBJ_TYPE_PROCEDURE diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 64dea95..8b0d407 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -310,7 +310,7 @@ proc_print(Environment *env, Object *obj) { Object *car = extract_car_with_type(env, obj, OBJ_TYPE_STRING); StringView scanner = (StringView) { .start = car->string, - .n = car->string_n, + .n = array_size(car->string), }; while (scanner.n != 0) { char c = sv_next(&scanner); -- cgit v1.2.1