Add type-checking functions and improve error handling in utils.hex; update tests accordingly. No longer freeing symbols (need to check references first).
h3rald h3rald@h3rald.com
Wed, 02 Apr 2025 13:41:56 +0200
4 files changed,
75 insertions(+),
34 deletions(-)
M
lib/utils.hex
→
lib/utils.hex
@@ -17,6 +17,27 @@ "_when_q" #
"_when_cond" # ) "when" :: +;; isi +;; a -> i +;; Pushes %%0x1%% on the stack if %:a%% is an integer, %%0x0%% otherwise. +( + type "integer" == +) "isi" :: + +;; iss +;; a -> i +;; Pushes $0x1$$ on the stack if %:a%% is a string, $0x0$$ otherwise. +( + type "string" == +) "iss" :: + +;; isq +;; a -> i +;; Pushes $0x1$$ on the stack if %%a%% is a quotation, $0x0$$ otherwise. +( + type "quotation" == +) "isq" :: + ;;; begins ;; s1 s2 -> s3 ;; Pushes $0x1$$ on the stack if %:s1%% begins with %:s2%%, or $0x0$$ otherwise.@@ -25,6 +46,12 @@ "_begins_prefix" :
"_begins_s" : 0x1 "_begins_result" : 0x0 "_begins_c" : + (_begins_prefix iss not) + ("[symbol begins] A string prefix is required" throw) + when + (_begins_s iss not) + ("[symbol begins] A string item is required" throw) + when (_begins_s len _begins_prefix len <) (0x0 "_begins_result" :) (@@ -58,6 +85,12 @@ (
"_ends_suffix" : "_ends_s" : 0x1 "_ends_result" : + (_ends_suffix iss not) + ("[symbol ends] A string suffix is required" throw) + when + (_ends_s iss not) + ("[symbol ends] A string item is required" throw) + when _ends_suffix len 0x1 - "_ends_c" : (_ends_s len _ends_suffix len <) (0x0 "_ends_result" :)@@ -106,27 +139,6 @@ "_cleanup_item" #
"_cleanup_c" # ) "cleanup" :: -;; isi -;; a -> i -;; Pushes %%0x1%% on the stack if %:a%% is an integer, %%0x0%% otherwise. -( - type "integer" == -) "isi" :: - -;; iss -;; a -> i -;; Pushes $0x1$$ on the stack if %:a%% is a string, $0x0$$ otherwise. -( - type "string" == -) "iss" :: - -;; isq -;; a -> i -;; Pushes $0x1$$ on the stack if %%a%% is a quotation, $0x0$$ otherwise. -( - type "quotation" == -) "isq" :: - ;;; ipop ;; s -> i ;; Stores symbol %%s%% by popping an integer from the stack, throws an error otherwise.@@ -229,7 +241,7 @@ 0x0 "_is-str" :
(_list iss) ( (_item iss not) - ("[symbol push] A string item is required" fail) + ("[symbol push] A string item is required" throw) when 0x1 "_is-str" : _list "" split "_list" :@@ -312,7 +324,7 @@ "_rep" :
"_src" : "_text" : (_text iss _src iss _rep iss and and not) - ("[symbol replace-all] Three strings required." fail) + ("[symbol replace-all] Three strings required." throw) when (_text _src index 0x0 >=) (_text _src _rep replace "_text" :)@@ -328,7 +340,7 @@ (
"_list" qpop () "_result" : (_list len 0x0 ==) - ("[symbol min] Not enough items" fail) + ("[symbol min] Not enough items" throw) when 0x0 get "_result" : 0x1 "_c" :@@ -351,7 +363,7 @@ (
"_list" qpop () "_result" : (_list len 0x0 ==) - ("[symbol max] Not enough items" fail) + ("[symbol max] Not enough items" throw) when 0x0 get "_result" : 0x1 "_c" :
M
scripts/test.hex
→
scripts/test.hex
@@ -290,10 +290,34 @@ ) len "130" hex ==
) ;150 - ;;; utils.hex tests ;;; + ;------------------------------------------------------------------------; + ; utils.hex tests ; + ;------------------------------------------------------------------------; + ("aa" iss) + (0x0 iss not) + ;152 + + ((a b c) iss not) + ((a b c) isq) + ("sdgas" isq not) + (0x0 isq not) + ;156 + + (0x1 isi) + ("aaa" isi not) + (("test") isi not) ("This is a test" "This" begins) + ;160 + ("This is a test" "this" begins not) - ;152 + ;((0x0 "aaa" begins) (error) try _ "[symbol begins] A string item is required" ==) + ;(("aaa" () begins) (error) try _ "[symbol begins] A string prefix is required" ==) + ("This is a test" "test" ends) + ;164 + + ("This is a test" "Test" ends not) + ;((0x0 "aaa" ends) (error) try _ "[symbol ends] A string item is required" ==) + (("aaa" () ends) (error) try "[symbol ends] A string suffix is required" ==) ) "TESTS" :
M
src/stack.c
→
src/stack.c
@@ -233,6 +233,7 @@ for (size_t i = 0; i < size; i++)
{ if (quotation[i]) { + hex_debug(ctx, "FREE: item #%zu", i); hex_free_item(ctx, quotation[i]); // Free each item } }@@ -242,43 +243,48 @@ void hex_free_item(hex_context_t *ctx, hex_item_t *item)
{ if (item == NULL) return; - - hex_debug_item(ctx, "FREE", item); switch (item->type) { case HEX_TYPE_STRING: if (item->data.str_value) { + hex_debug_item(ctx, "FREE", item); free(item->data.str_value); item->data.str_value = NULL; // Prevent double free } + free(item); // Free the item itself + item = NULL; break; case HEX_TYPE_QUOTATION: if (item->data.quotation_value) { + hex_debug_item(ctx, "FREE", item); hex_free_list(ctx, item->data.quotation_value, item->quotation_size); - // free(item->data.quotation_value); item->data.quotation_value = NULL; // Prevent double free } + free(item); // Free the item itself + item = NULL; break; case HEX_TYPE_NATIVE_SYMBOL: case HEX_TYPE_USER_SYMBOL: if (item->token) { + // TODO: Cannot free the token here, as it may be shared with other items + // Need to implement a reference counting mechanism for symbols + /* + hex_debug_item(ctx, "FREE", item); hex_free_token(item->token); item->token = NULL; // Prevent double free + */ } break; default: break; } - - free(item); // Free the item itself - item = NULL; } hex_token_t *hex_copy_token(hex_context_t *ctx, const hex_token_t *token)
M
src/symbols.c
→
src/symbols.c
@@ -2389,7 +2389,6 @@ HEX_FREE(ctx, catch_block);
return 1; } HEX_POP(ctx, try_block); - ; if (try_block->type == HEX_TYPE_INVALID) { HEX_FREE(ctx, catch_block);