From 51c6bdcea93faa29a810b669a4f782c476de6561 Mon Sep 17 00:00:00 2001 From: William Bell <62452284+Ugric@users.noreply.github.com> Date: Wed, 22 Oct 2025 20:33:01 +0100 Subject: [PATCH] fix seg fault in dictionary creation --- src/parser/assignable/access/access.c | 2 +- src/parser/parser.c | 2 +- src/runtime/internals/hashmap/hashmap.c | 34 ++++++++++++++++++------- src/translator/translator.c | 1 + tests/hashmap_creation_seg_fault.ar | 2 ++ tests/hashmap_order.ar | 6 +++++ 6 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 tests/hashmap_creation_seg_fault.ar create mode 100644 tests/hashmap_order.ar diff --git a/src/parser/assignable/access/access.c b/src/parser/assignable/access/access.c index 5f2a561..3850d2a 100644 --- a/src/parser/assignable/access/access.c +++ b/src/parser/assignable/access/access.c @@ -16,7 +16,6 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index, ParsedValue *to_access) { Token *first_token = darray_get(tokens, *index); - (*index)++; ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); if (first_token->type == TOKEN_DOT) { ParsedAccess *parsedAccess = checked_malloc(sizeof(ParsedAccess)); @@ -24,6 +23,7 @@ ParsedValueReturn parse_access(char *file, DArray *tokens, size_t *index, parsedAccess->access = NULL; parsedValue->type = AST_ACCESS; parsedValue->data = parsedAccess; + (*index)++; ArErr err = error_if_finished(file, tokens, index); if (err.exists) { free_parsed(parsedValue); diff --git a/src/parser/parser.c b/src/parser/parser.c index 9be5894..b110c35 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -199,7 +199,7 @@ ArErr parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) { if (expecting_new_line) { Token *token = darray_get(tokens, old_index); return create_err(token->line, token->column, token->length, file, - "Syntax Error", "expected new line"); + "Syntax Error", "invalid syntax"); } expecting_new_line = true; darray_push(parsed, parsed_code.value); diff --git a/src/runtime/internals/hashmap/hashmap.c b/src/runtime/internals/hashmap/hashmap.c index 1a7ad56..6ec84f2 100644 --- a/src/runtime/internals/hashmap/hashmap.c +++ b/src/runtime/internals/hashmap/hashmap.c @@ -25,26 +25,42 @@ struct hashmap_GC *createHashmap_GC() { t->inline_count = 0; return t; } -void hashmap_GC_to_array(struct hashmap_GC *t, struct node_GC**array, - size_t *array_length) { + +static int compare_node_asc(const void *a, const void *b) { + const struct node_GC *na = (const struct node_GC *)a; + const struct node_GC *nb = (const struct node_GC *)b; + + // Ascending order (smallest order first) + if (na->order < nb->order) return -1; + if (na->order > nb->order) return 1; + return 0; +} + +void hashmap_GC_to_array(struct hashmap_GC *t, struct node_GC **array, + size_t *array_length) { size_t array_size = 8; *array_length = 0; *array = ar_alloc(array_size * sizeof(struct node_GC)); + for (size_t i = 0; i < t->inline_count; i++) { - if (*array_length >=array_size) { - array_size*=2; - *array=ar_realloc(*array, array_size * sizeof(struct node_GC)); + if (*array_length >= array_size) { + array_size *= 2; + *array = ar_realloc(*array, array_size * sizeof(struct node_GC)); } (*array)[(*array_length)++] = t->inline_values[i]; } + for (size_t i = 0; i < t->size; i++) { - if (!t->list[i]) continue; - if (*array_length >=array_size) { - array_size*=2; - *array=ar_realloc(*array, array_size * sizeof(struct node_GC)); + if (!t->list[i]) + continue; + if (*array_length >= array_size) { + array_size *= 2; + *array = ar_realloc(*array, array_size * sizeof(struct node_GC)); } (*array)[(*array_length)++] = *t->list[i]; } + + qsort(*array, *array_length, sizeof(struct node_GC), compare_node_asc); } void clear_hashmap_GC(struct hashmap_GC *t) { diff --git a/src/translator/translator.c b/src/translator/translator.c index bd4cc2f..89aa852 100644 --- a/src/translator/translator.c +++ b/src/translator/translator.c @@ -189,6 +189,7 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue, push_instruction_byte(translated, OP_LOAD_SETITEM_METHOD); uint8_t setitemRegister = translated->registerAssignment++; + set_registers(translated, translated->registerAssignment); push_instruction_byte(translated, OP_COPY_TO_REGISTER); push_instruction_byte(translated, 0); diff --git a/tests/hashmap_creation_seg_fault.ar b/tests/hashmap_creation_seg_fault.ar new file mode 100644 index 0000000..0f3d8d4 --- /dev/null +++ b/tests/hashmap_creation_seg_fault.ar @@ -0,0 +1,2 @@ +while (true) do + {"z": 1, "b": 2, "c": 3, "a": 7} \ No newline at end of file diff --git a/tests/hashmap_order.ar b/tests/hashmap_order.ar new file mode 100644 index 0000000..ec4bb79 --- /dev/null +++ b/tests/hashmap_order.ar @@ -0,0 +1,6 @@ +x = {} +x.z = 1 +x.b = 2 +x.c = 3 +x.a = 7 +term.log(x) \ No newline at end of file