diff options
Diffstat (limited to 'src/bootstrap')
-rw-r--r-- | src/bootstrap/darray.h | 23 | ||||
-rw-r--r-- | src/bootstrap/gc.c | 12 | ||||
-rw-r--r-- | src/bootstrap/objects.c | 26 | ||||
-rw-r--r-- | src/bootstrap/objects.h | 2 | ||||
-rw-r--r-- | src/bootstrap/primitives.c | 2 |
5 files changed, 37 insertions, 28 deletions
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 { | |||
25 | // Return the last element of the array. Can be used to build stacks. | 25 | // Return the last element of the array. Can be used to build stacks. |
26 | #define array_pop(ARR) (ARR)[--array_head(ARR)->size] | 26 | #define array_pop(ARR) (ARR)[--array_head(ARR)->size] |
27 | 27 | ||
28 | // Insert N bytes from the SRC array into the ARR dynamic array. | ||
29 | #define array_insert(ARR, SRC, N) \ | ||
30 | ((ARR) = _array_insert(ARR, SRC, N, sizeof(*(ARR)))) | ||
31 | |||
28 | // Free the memory from the original allocated position. | 32 | // Free the memory from the original allocated position. |
29 | #define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0) | 33 | #define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0) |
30 | 34 | ||
@@ -52,4 +56,23 @@ _array_maybe_grow(void *arr, size_t type_size) { | |||
52 | return arr; | 56 | return arr; |
53 | } | 57 | } |
54 | 58 | ||
59 | static inline | ||
60 | char * _array_insert(char *arr, const char *src, size_t n_bytes, size_t type_size) { | ||
61 | ArrayHeader *head = array_head(arr); | ||
62 | size_t new_size = n_bytes + head->size; | ||
63 | if (new_size >= head->cap * type_size) { | ||
64 | if (head->cap == 0) { | ||
65 | head->cap = 1; | ||
66 | } | ||
67 | while (new_size >= head->cap * type_size) { | ||
68 | head->cap *= 2; | ||
69 | } | ||
70 | head = realloc(head, head->cap * type_size + sizeof(ArrayHeader)); | ||
71 | } | ||
72 | arr = (char *)head + sizeof(ArrayHeader); | ||
73 | memcpy((arr + head->size), src, n_bytes); | ||
74 | head->size = new_size; | ||
75 | return arr; | ||
76 | } | ||
77 | |||
55 | #endif // BDL_DARRAY_H | 78 | #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) { | |||
121 | if (!obj->marked) { | 121 | if (!obj->marked) { |
122 | // Free heap allocated memory for this object if needed. | 122 | // Free heap allocated memory for this object if needed. |
123 | if (obj->type == OBJ_TYPE_SYMBOL) { | 123 | if (obj->type == OBJ_TYPE_SYMBOL) { |
124 | if (obj->symbol != NULL) { | 124 | array_free(obj->symbol); |
125 | free(obj->symbol); | ||
126 | } | ||
127 | obj->symbol = NULL; | ||
128 | obj->symbol_n = 0; | ||
129 | } else if (obj->type == OBJ_TYPE_STRING) { | 125 | } else if (obj->type == OBJ_TYPE_STRING) { |
130 | if (obj->symbol != NULL) { | 126 | array_free(obj->string); |
131 | free(obj->string); | ||
132 | } | ||
133 | obj->string = NULL; | ||
134 | obj->string_n = 0; | ||
135 | } | 127 | } |
136 | gc.free_objects.buf[gc.free_objects.size++] = i; | 128 | gc.free_objects.buf[gc.free_objects.size++] = i; |
137 | } | 129 | } |
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) { | |||
30 | Object * | 30 | Object * |
31 | make_symbol(StringView sv) { | 31 | make_symbol(StringView sv) { |
32 | Object *obj = alloc_object(OBJ_TYPE_SYMBOL); | 32 | Object *obj = alloc_object(OBJ_TYPE_SYMBOL); |
33 | obj->symbol = malloc(sizeof(char) * sv.n); | 33 | obj->symbol = NULL; |
34 | memcpy(obj->symbol, sv.start, sv.n); | 34 | array_init(obj->symbol, sv.n); |
35 | obj->symbol_n = sv.n; | 35 | array_insert(obj->symbol, sv.start, sv.n); |
36 | return obj; | 36 | return obj; |
37 | } | 37 | } |
38 | 38 | ||
@@ -40,20 +40,16 @@ Object * | |||
40 | make_string(void) { | 40 | make_string(void) { |
41 | Object *obj = alloc_object(OBJ_TYPE_STRING); | 41 | Object *obj = alloc_object(OBJ_TYPE_STRING); |
42 | obj->string = NULL; | 42 | obj->string = NULL; |
43 | obj->string_n = 0; | 43 | array_init(obj->string, 0); |
44 | return obj; | 44 | return obj; |
45 | } | 45 | } |
46 | 46 | ||
47 | void | 47 | void |
48 | append_string(Object *obj, const StringView sv) { | 48 | append_string(Object *obj, const StringView sv) { |
49 | assert(obj != NULL); | ||
50 | assert(obj->type == OBJ_TYPE_STRING); | ||
51 | if (sv.n == 0) { | 49 | if (sv.n == 0) { |
52 | return; | 50 | return; |
53 | } | 51 | } |
54 | obj->string = realloc(obj->string, (obj->string_n + sv.n) * sizeof(char)); | 52 | array_insert(obj->string, sv.start, sv.n); |
55 | memcpy(obj->string + obj->string_n, sv.start, sv.n); | ||
56 | obj->string_n += sv.n; | ||
57 | } | 53 | } |
58 | 54 | ||
59 | void | 55 | void |
@@ -87,10 +83,10 @@ display(Object *root) { | |||
87 | printf("()"); | 83 | printf("()"); |
88 | } break; | 84 | } break; |
89 | case OBJ_TYPE_STRING: { | 85 | case OBJ_TYPE_STRING: { |
90 | printf("\"%.*s\"", (int)root->string_n, root->string); | 86 | printf("\"%.*s\"", (int)array_size(root->string), root->string); |
91 | } break; | 87 | } break; |
92 | case OBJ_TYPE_SYMBOL: { | 88 | case OBJ_TYPE_SYMBOL: { |
93 | printf(":%.*s", (int)root->symbol_n, root->symbol); | 89 | printf(":%.*s", (int)array_size(root->symbol), root->symbol); |
94 | } break; | 90 | } break; |
95 | case OBJ_TYPE_PAIR: { | 91 | case OBJ_TYPE_PAIR: { |
96 | printf("("); | 92 | printf("("); |
@@ -118,20 +114,20 @@ obj_eq(Object *a, Object* b) { | |||
118 | return a->fixnum == b->fixnum; | 114 | return a->fixnum == b->fixnum; |
119 | } break; | 115 | } break; |
120 | case OBJ_TYPE_STRING: { | 116 | case OBJ_TYPE_STRING: { |
121 | if (a->string_n != b->string_n) { | 117 | if (array_size(a->string) != array_size(b->string)) { |
122 | return false; | 118 | return false; |
123 | } | 119 | } |
124 | for (size_t i = 0; i < a->string_n; i++) { | 120 | for (size_t i = 0; i < array_size(a->string); i++) { |
125 | if (a->string[i] != b->string[i]) { | 121 | if (a->string[i] != b->string[i]) { |
126 | return false; | 122 | return false; |
127 | } | 123 | } |
128 | } | 124 | } |
129 | } break; | 125 | } break; |
130 | case OBJ_TYPE_SYMBOL: { | 126 | case OBJ_TYPE_SYMBOL: { |
131 | if (a->symbol_n != b->symbol_n) { | 127 | if (array_size(a->symbol) != array_size(b->symbol)) { |
132 | return false; | 128 | return false; |
133 | } | 129 | } |
134 | for (size_t i = 0; i < a->symbol_n; i++) { | 130 | for (size_t i = 0; i < array_size(a->symbol); i++) { |
135 | if (a->symbol[i] != b->symbol[i]) { | 131 | if (a->symbol[i] != b->symbol[i]) { |
136 | return false; | 132 | return false; |
137 | } | 133 | } |
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 { | |||
27 | // OBJ_TYPE_STRING | 27 | // OBJ_TYPE_STRING |
28 | struct { | 28 | struct { |
29 | char *string; | 29 | char *string; |
30 | size_t string_n; | ||
31 | }; | 30 | }; |
32 | 31 | ||
33 | // OBJ_TYPE_PAIR | 32 | // OBJ_TYPE_PAIR |
@@ -39,7 +38,6 @@ typedef struct Object { | |||
39 | // OBJ_TYPE_SYMBOL | 38 | // OBJ_TYPE_SYMBOL |
40 | struct { | 39 | struct { |
41 | char *symbol; | 40 | char *symbol; |
42 | size_t symbol_n; | ||
43 | }; | 41 | }; |
44 | 42 | ||
45 | // OBJ_TYPE_PROCEDURE | 43 | // 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) { | |||
310 | Object *car = extract_car_with_type(env, obj, OBJ_TYPE_STRING); | 310 | Object *car = extract_car_with_type(env, obj, OBJ_TYPE_STRING); |
311 | StringView scanner = (StringView) { | 311 | StringView scanner = (StringView) { |
312 | .start = car->string, | 312 | .start = car->string, |
313 | .n = car->string_n, | 313 | .n = array_size(car->string), |
314 | }; | 314 | }; |
315 | while (scanner.n != 0) { | 315 | while (scanner.n != 0) { |
316 | char c = sv_next(&scanner); | 316 | char c = sv_next(&scanner); |