Fixes.
@@ -94,7 +94,6 @@ ("aaaaa" len 0x5 ==)
("hello" " world" cat "hello world" ==) ;36 - ((0x1 "a") ("b") cat (0x1 "a" "b") ==) ((0x1 0x3 puts "aaa") len 0x4 ==) ((0x2 0x3 0x4) 0x2 get 0x4 ==)
@@ -90,11 +90,16 @@ return;
} func_item->type = HEX_TYPE_NATIVE_SYMBOL; func_item->data.fn_value = func; + // Need to create a fake token for native symbols as well. + func_item->token = malloc(sizeof(hex_token_t)); + func_item->token->type = HEX_TOKEN_SYMBOL; + func_item->token->value = strdup(name); + func_item->token->position = NULL; if (hex_set_symbol(ctx, name, func_item, 1) != 0) { hex_error(ctx, "Error: Failed to register native symbol '%s'", name); - free(func_item); + hex_free_item(ctx, func_item); } }@@ -105,9 +110,20 @@ for (size_t i = 0; i < ctx->registry->size; i++)
{ if (strcmp(ctx->registry->entries[i]->key, key) == 0) { + if (ctx->registry->entries[i]->value == NULL) + { + hex_error(ctx, "[get symbol] Registry entry value is NULL for key: %s", key); + return 0; + } hex_debug(ctx, "LOOK: %s", key); - *result = *ctx->registry->entries[i]->value; - //hex_debug_item(ctx, "DONE: ", result); + hex_item_t *item = hex_copy_item(ctx, ctx->registry->entries[i]->value); + if (item == NULL) + { + hex_error(ctx, "[get symbol] Failed to copy item for key: %s", key); + return 0; + } + *result = *item; + hex_debug_item(ctx, "DONE: ", result); return 1; } }
@@ -51,7 +51,6 @@ }
} else { - hex_debug_item(ctx, "Value: ", value); result = hex_push(ctx, value); } }@@ -140,7 +139,7 @@ {
hex_error(ctx, "[create quotation] Failed to allocate memory for item"); return NULL; } - item->operator = 0; + item->operator= 0; item->type = HEX_TYPE_QUOTATION; item->data.quotation_value = quotation; item->quotation_size = size;@@ -282,77 +281,187 @@ free(item); // Free the item itself
item = NULL; } -hex_item_t *hex_copy_item(hex_context_t *ctx, const hex_item_t *item) +hex_token_t *hex_copy_token(hex_context_t *ctx, const hex_token_t *token) { - hex_item_t *copy = malloc(sizeof(hex_item_t)); - if (copy == NULL) + if (!token) + { + hex_error(ctx, "[copy token] Token is NULL"); + return NULL; + } + + // Allocate memory for the new token + hex_token_t *copy = (hex_token_t *)malloc(sizeof(hex_token_t)); + if (!copy) { - hex_error(ctx, "[copy item] Failed to allocate memory for item"); + hex_error(ctx, "[copy token] Failed to allocate memory for token copy"); return NULL; } - copy->type = item->type; - switch (item->type) + // Copy basic fields + copy->type = token->type; + copy->quotation_size = token->quotation_size; + + // Copy the token's value + if (token->value) { - case HEX_TYPE_STRING: - copy->data.str_value = strdup(item->data.str_value); - if (copy->data.str_value == NULL) + copy->value = strdup(token->value); + if (!copy->value) { - hex_error(ctx, "[copy item] Failed to allocate memory for string"); + hex_error(ctx, "[copy token] Failed to copy token value"); free(copy); return NULL; } - break; - - case HEX_TYPE_INTEGER: - copy->data.int_value = item->data.int_value; - break; + } + else + { + copy->value = NULL; + } - case HEX_TYPE_QUOTATION: - copy->quotation_size = item->quotation_size; - copy->data.quotation_value = malloc(copy->quotation_size * sizeof(hex_item_t *)); - if (copy->data.quotation_value == NULL) + // Copy the file position if it exists + if (token->position) + { + copy->position = (hex_file_position_t *)malloc(sizeof(hex_file_position_t)); + if (!copy->position) { - hex_error(ctx, "[copy item] Failed to allocate memory for quotation"); + free(copy->value); free(copy); + hex_error(ctx, "[copy token] Failed to allocate memory for position"); return NULL; } - for (size_t i = 0; i < copy->quotation_size; i++) + + // Copy filename string + if (token->position->filename) { - copy->data.quotation_value[i] = hex_copy_item(ctx, item->data.quotation_value[i]); - if (copy->data.quotation_value[i] == NULL) + copy->position->filename = strdup(token->position->filename); + if (!copy->position->filename) { - hex_free_list(ctx, copy->data.quotation_value, i); - free(copy->data.quotation_value); + free(copy->position); + free(copy->value); free(copy); + hex_error(ctx, "[copy token] Failed to copy filename"); return NULL; } } + else + { + copy->position->filename = NULL; + } + + copy->position->line = token->position->line; + copy->position->column = token->position->column; + } + else + { + copy->position = NULL; + } + + return copy; +} + +hex_item_t *hex_copy_item(hex_context_t *ctx, const hex_item_t *item) +{ + if (!item) + { + hex_error(ctx, "[copy item] Item is NULL"); + return NULL; + } + + // Allocate memory for the new hex_item_t structure + hex_item_t *copy = (hex_item_t *)malloc(sizeof(hex_item_t)); + if (!copy) + { + hex_error(ctx, "[copy item] Failed to allocate memory for item copy"); + return NULL; + } + + // Copy basic fields + copy->type = item->type; + copy->operator= item->operator; + copy->quotation_size = item->quotation_size; + + // Copy the union field based on the type + switch (item->type) + { + case HEX_TYPE_INTEGER: + copy->data.int_value = item->data.int_value; break; - case HEX_TYPE_NATIVE_SYMBOL: - case HEX_TYPE_USER_SYMBOL: - copy->token = malloc(sizeof(hex_token_t)); - if (copy->token == NULL) + case HEX_TYPE_STRING: + if (item->data.str_value) { - hex_error(ctx, "[copy item] Failed to allocate memory for token"); - free(copy); - return NULL; + copy->data.str_value = strdup(item->data.str_value); // Deep copy the string + if (!copy->data.str_value) + { + hex_free_item(ctx, copy); + hex_error(ctx, "[copy item] Failed to copy string value"); + return NULL; + } + } + else + { + copy->data.str_value = NULL; + } + break; + + case HEX_TYPE_QUOTATION: + if (item->data.quotation_value && item->quotation_size > 0) + { + copy->data.quotation_value = (hex_item_t **)malloc(item->quotation_size * sizeof(hex_item_t *)); + if (!copy->data.quotation_value) + { + hex_free_item(ctx, copy); + hex_error(ctx, "[copy item] Failed to allocate memory for quotation array"); + return NULL; + } + + for (size_t i = 0; i < item->quotation_size; ++i) + { + copy->data.quotation_value[i] = hex_copy_item(ctx, item->data.quotation_value[i]); // Recursively copy each item + if (!copy->data.quotation_value[i]) + { + // Cleanup on failure + hex_free_list(ctx, copy->data.quotation_value, i); // Free copied items + hex_free_item(ctx, copy); + hex_error(ctx, "[copy item] Failed to copy quotation item"); + return NULL; + } + } } - copy->token->value = strdup(item->token->value); - if (copy->token->value == NULL) + else { - hex_error(ctx, "[copy item] Failed to allocate memory for token value"); - hex_free_token(copy->token); - hex_free_item(ctx, copy); - return NULL; + copy->data.quotation_value = NULL; } break; + case HEX_TYPE_NATIVE_SYMBOL: + copy->data.fn_value = item->data.fn_value; // Copy function pointer for native symbols + break; + + case HEX_TYPE_USER_SYMBOL: + // User symbols do not have a function pointer, so no additional copying here + break; + default: - hex_error(ctx, "[copy item] Failed to copy %s item", hex_type(item->type)); + // Unsupported type + hex_error(ctx, "[copy item] Unsupported item type: %d", item->type); hex_free_item(ctx, copy); return NULL; + } + + // Copy the token field for native and user symbols + if (item->type == HEX_TYPE_NATIVE_SYMBOL || item->type == HEX_TYPE_USER_SYMBOL) + { + copy->token = hex_copy_token(ctx, item->token); + if (!copy->token) + { + hex_free_item(ctx, copy); + hex_error(ctx, "[copy item] Failed to copy token"); + return NULL; + } + } + else + { + copy->token = NULL; } return copy;
@@ -234,7 +234,7 @@ return 1;
} if (item->type != HEX_TYPE_QUOTATION) { - hex_error(ctx, "[symbol .] Quotation required"); + hex_error(ctx, "[symbol .] Quotation required, got %s", hex_type(item->type)); HEX_FREE(ctx, item); return 1; }@@ -1202,7 +1202,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; } // Different types => false@@ -1239,7 +1239,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; } // Different types => true@@ -1248,7 +1248,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; }@@ -1276,7 +1276,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; }@@ -1304,7 +1304,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; }@@ -1332,7 +1332,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; }@@ -1360,7 +1360,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; }@@ -1390,7 +1390,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; } hex_error(ctx, "[symbol and] Two integers required");@@ -1422,8 +1422,8 @@ int result = hex_push_integer(ctx, a->data.int_value || b->data.int_value);
if (result != 0) { HEX_FREE(ctx, a); - HEX_FREE(ctx, b); - } + HEX_FREE(ctx, b); + } return result; } hex_error(ctx, "[symbol or] Two integers required");@@ -1452,7 +1452,7 @@ int result = hex_push_integer(ctx, !a->data.int_value);
if (result != 0) { HEX_FREE(ctx, a); - } + } return result; } hex_error(ctx, "[symbol not] Integer required");@@ -1497,7 +1497,7 @@ if (result != 0)
{ HEX_FREE(ctx, a); HEX_FREE(ctx, b); - } + } return result; } hex_error(ctx, "[symbol xor] Two integers required");@@ -1515,7 +1515,7 @@ {
hex_error(ctx, "[symbol cat] Memory allocation failed"); return 1; } - //HEX_POP(ctx, value); + // HEX_POP(ctx, value); value = hex_pop(ctx); if (value->type == HEX_TYPE_INVALID) {