all repos — hex @ a9c2ed0c077f37c6bcf0269603ca8ff769b20a21

A tiny, minimalist, slightly-esoteric concatenative programming lannguage.

Add debug integrity checks for quotations and stack validation; enhances debugging capabilities and prevents aliasing issues.
h3rald h3rald@h3rald.com
Wed, 10 Sep 2025 18:13:55 +0200
commit

a9c2ed0c077f37c6bcf0269603ca8ff769b20a21

parent

afed7c4368d64c1dbd7c4ccee58214292356cb55

4 files changed, 140 insertions(+), 0 deletions(-)

jump to
M src/hex.csrc/hex.c

@@ -381,6 +381,15 @@ int hex_symbol_stack(hex_context_t *ctx);

int hex_symbol_drop(hex_context_t *ctx); int hex_symbol_timestamp(hex_context_t *ctx); +// Debug / integrity helpers (always callable; no-op stubs in non-DEBUG builds) +#ifdef DEBUG +int hex_validate_quotation_integrity(hex_context_t *ctx, const hex_item_t *item); +int hex_debug_validate_stack(hex_context_t *ctx); +#else +static inline int hex_validate_quotation_integrity(hex_context_t *ctx, const hex_item_t *item) { (void)ctx; (void)item; return 0; } +static inline int hex_debug_validate_stack(hex_context_t *ctx) { (void)ctx; return 0; } +#endif + // Opcodes uint8_t hex_symbol_to_opcode(const char *symbol); const char *hex_opcode_to_symbol(uint8_t opcode);

@@ -474,6 +483,11 @@ {

hex_error(ctx, "[push] Stack overflow"); return 1; } + if (ctx->settings && ctx->settings->debugging_enabled) + { + // Validate existing stack before modification + hex_debug_validate_stack(ctx); + } hex_debug_item(ctx, "PUSH", item); int result = 0;

@@ -550,6 +564,11 @@ }

else { hex_debug_item(ctx, "FAIL", item); + } + if (result == 0 && ctx->settings && ctx->settings->debugging_enabled) + { + // Validate stack after successful push + hex_debug_validate_stack(ctx); } return result; }

@@ -6730,6 +6749,57 @@ return 1;

} return 0; } + +#ifdef DEBUG +// Recursively validate that quotations do not share element pointers with siblings. +// Returns 0 on success, 1 if a potential aliasing issue is detected. +int hex_validate_quotation_integrity(hex_context_t *ctx, const hex_item_t *item) +{ + (void)ctx; + if (!item) + { + return 0; + } + if (item->type != HEX_TYPE_QUOTATION || item->quotation_size == 0) + { + return 0; + } + // Simple O(n^2) pointer identity check among siblings; acceptable for debug. + for (size_t i = 0; i < item->quotation_size; i++) + { + hex_item_t *a = item->data.quotation_value[i]; + for (size_t j = i + 1; j < item->quotation_size; j++) + { + if (a == item->data.quotation_value[j]) + { + hex_error(ctx, "[integrity] Quotation has duplicated element pointer at %zu and %zu", i, j); + return 1; + } + } + // Recurse + if (hex_validate_quotation_integrity(ctx, a) != 0) + { + return 1; + } + } + return 0; +} + +int hex_debug_validate_stack(hex_context_t *ctx) +{ + if (!ctx || !ctx->stack) { return 0; } + for (int i = 0; i <= ctx->stack->top; i++) + { + hex_item_t *it = ctx->stack->entries[i]; + if (it && hex_validate_quotation_integrity(ctx, it) != 0) + { + hex_error(ctx, "[integrity] Detected potential aliasing at stack index %d", i); + return 1; + } + } + return 0; +} +#endif //////////////////////////////////////// // Native Symbol Registration //
M src/hex.hsrc/hex.h

@@ -378,6 +378,15 @@ int hex_symbol_stack(hex_context_t *ctx);

int hex_symbol_drop(hex_context_t *ctx); int hex_symbol_timestamp(hex_context_t *ctx); +// Debug / integrity helpers (always callable; no-op stubs in non-DEBUG builds) +#ifdef DEBUG +int hex_validate_quotation_integrity(hex_context_t *ctx, const hex_item_t *item); +int hex_debug_validate_stack(hex_context_t *ctx); +#else +static inline int hex_validate_quotation_integrity(hex_context_t *ctx, const hex_item_t *item) { (void)ctx; (void)item; return 0; } +static inline int hex_debug_validate_stack(hex_context_t *ctx) { (void)ctx; return 0; } +#endif + // Opcodes uint8_t hex_symbol_to_opcode(const char *symbol); const char *hex_opcode_to_symbol(uint8_t opcode);
M src/stack.csrc/stack.c

@@ -42,6 +42,11 @@ {

hex_error(ctx, "[push] Stack overflow"); return 1; } + if (ctx->settings && ctx->settings->debugging_enabled) + { + // Validate existing stack before modification + hex_debug_validate_stack(ctx); + } hex_debug_item(ctx, "PUSH", item); int result = 0;

@@ -118,6 +123,11 @@ }

else { hex_debug_item(ctx, "FAIL", item); + } + if (result == 0 && ctx->settings && ctx->settings->debugging_enabled) + { + // Validate stack after successful push + hex_debug_validate_stack(ctx); } return result; }
M src/symbols.csrc/symbols.c

@@ -2804,6 +2804,57 @@ }

return 0; } +#ifdef DEBUG +// Recursively validate that quotations do not share element pointers with siblings. +// Returns 0 on success, 1 if a potential aliasing issue is detected. +int hex_validate_quotation_integrity(hex_context_t *ctx, const hex_item_t *item) +{ + (void)ctx; + if (!item) + { + return 0; + } + if (item->type != HEX_TYPE_QUOTATION || item->quotation_size == 0) + { + return 0; + } + // Simple O(n^2) pointer identity check among siblings; acceptable for debug. + for (size_t i = 0; i < item->quotation_size; i++) + { + hex_item_t *a = item->data.quotation_value[i]; + for (size_t j = i + 1; j < item->quotation_size; j++) + { + if (a == item->data.quotation_value[j]) + { + hex_error(ctx, "[integrity] Quotation has duplicated element pointer at %zu and %zu", i, j); + return 1; + } + } + // Recurse + if (hex_validate_quotation_integrity(ctx, a) != 0) + { + return 1; + } + } + return 0; +} + +int hex_debug_validate_stack(hex_context_t *ctx) +{ + if (!ctx || !ctx->stack) { return 0; } + for (int i = 0; i <= ctx->stack->top; i++) + { + hex_item_t *it = ctx->stack->entries[i]; + if (it && hex_validate_quotation_integrity(ctx, it) != 0) + { + hex_error(ctx, "[integrity] Detected potential aliasing at stack index %d", i); + return 1; + } + } + return 0; +} +#endif + //////////////////////////////////////// // Native Symbol Registration // ////////////////////////////////////////