Implemented symbol table support.
h3rald h3rald@h3rald.com
Thu, 19 Dec 2024 10:04:07 +0100
4 files changed,
64 insertions(+),
64 deletions(-)
M
src/hex.h
→
src/hex.h
@@ -375,11 +375,10 @@ void hex_header(hex_context_t *ctx, uint8_t header[8]);
int hex_validate_header(uint8_t header[8]); // Symbol table -void hex_symboltable_init(hex_context_t *ctx); -void hex_symboltable_free(hex_context_t *ctx); int hex_symboltable_set(hex_context_t *ctx, const char *symbol); -int hex_symboltable_get(hex_context_t *ctx, const char *symbol); -void hex_decode_bytecode_symboltable(hex_context_t *ctx, const uint8_t *bytecode, size_t size); +int hex_symboltable_get_index(hex_context_t *ctx, const char *symbol); +char *hex_symboltable_get_value(hex_context_t *ctx, uint16_t index); +int hex_decode_bytecode_symboltable(hex_context_t *ctx, uint8_t **bytecode, size_t *size, size_t count); uint8_t *hex_encode_bytecode_symboltable(hex_context_t *ctx, size_t *out_size); // REPL and initialization
M
src/interpreter.c
→
src/interpreter.c
@@ -19,6 +19,8 @@ context.stack_trace.size = 0;
context.settings.debugging_enabled = 0; context.settings.errors_enabled = 1; context.settings.stack_trace_enabled = 1; + context.symbol_table.count = 0; + context.symbol_table.symbols = malloc(HEX_MAX_USER_SYMBOLS * sizeof(char *)); return context; }
M
src/symboltable.c
→
src/symboltable.c
@@ -2,22 +2,6 @@ #ifndef HEX_H
#include "hex.h" #endif -void hex_symboltable_init(hex_context_t *ctx) -{ - ctx->symbol_table.count = 0; - ctx->symbol_table.symbols = malloc(HEX_MAX_USER_SYMBOLS * sizeof(char *)); -} - -void hex_symboltable_free(hex_context_t *ctx) -{ - for (uint16_t i = 0; i < ctx->symbol_table.count; ++i) - { - free(ctx->symbol_table.symbols[i]); - } - free(ctx->symbol_table.symbols); - ctx->symbol_table.count = 0; -} - // Add a symbol to the table if it does not already exist // Returns 0 on success, -1 if the symbol is too long or table is full int hex_symboltable_set(hex_context_t *ctx, const char *symbol)@@ -53,8 +37,9 @@ return 0;
} // Get the index of a symbol in the table, or -1 if not found -int hex_symboltable_get(hex_context_t *ctx, const char *symbol) +int hex_symboltable_get_index(hex_context_t *ctx, const char *symbol) { + hex_debug(ctx, "Symbol Table - looking up symbol: %s", symbol); hex_symbol_table_t *table = &ctx->symbol_table; for (uint16_t i = 0; i < table->count; ++i) {@@ -64,32 +49,47 @@ return i;
} } return -1; // Symbol not found +} + +// Get a symbol from the table by index +char *hex_symboltable_get_value(hex_context_t *ctx, uint16_t index) +{ + if (index >= ctx->symbol_table.count) + { + return NULL; + } + return ctx->symbol_table.symbols[index]; } // Decode a bytecode's symbol table into the hex_symbol_table_t structure // Assumes input is well-formed -void hex_decode_bytecode_symboltable(hex_context_t *ctx, const uint8_t *bytecode, size_t size) +int hex_decode_bytecode_symboltable(hex_context_t *ctx, uint8_t **bytecode, size_t *size, size_t total) { hex_symbol_table_t *table = &ctx->symbol_table; table->count = 0; - size_t offset = 0; - while (offset < size) + for (size_t i = 0; i < total; i++) { - if (table->count >= HEX_MAX_USER_SYMBOLS) + hex_debug(ctx, "Decoding symbol %zu", i); + size_t len = (size_t)(*bytecode)[0]; + (*bytecode)++; + *size -= 1; + + char *symbol = malloc(len + 1); + if (symbol == NULL) { - break; // Prevent overflow + hex_error(ctx, "Memory allocation failed"); + // Handle memory allocation failure + return -1; } - - uint8_t str_len = bytecode[offset++]; - char *symbol = malloc(str_len + 1); - memcpy(symbol, bytecode + offset, str_len); - symbol[str_len] = '\0'; - offset += str_len; - + memcpy(symbol, *bytecode, len); + symbol[len] = '\0'; hex_symboltable_set(ctx, symbol); free(symbol); + *bytecode += len; + *size -= len; } + return 0; } // Encode the symbol table into a bytecode representation
M
src/vm.c
→
src/vm.c
@@ -532,8 +532,8 @@ else
{ // Add to symbol table hex_symboltable_set(ctx, value); - int index = hex_symboltable_get(ctx, value); - hex_debug(ctx, "LOOKUP[%d]: %d (%s)", index, value); + int index = hex_symboltable_get_index(ctx, value); + hex_debug(ctx, "LOOKUP[1]: %d (%s)", index, value); // Check if we need to resize the buffer (size + 1 opcode + 2 max index) if (*size + 1 + 2 > *capacity) {@@ -585,7 +585,6 @@ hex_token_t *token;
size_t capacity = 128; size_t size = 0; uint8_t *bytecode = (uint8_t *)malloc(capacity); - hex_symboltable_init(ctx); if (!bytecode) { hex_error(ctx, "Memory allocation failed");@@ -791,7 +790,6 @@
hex_item_t item = hex_string_item(ctx, value); *result = item; hex_debug(ctx, "PUSHST[%zu]: %s", length, value); - free(value); return 0; }@@ -831,41 +829,35 @@ }
int hex_interpret_bytecode_user_symbol(hex_context_t *ctx, uint8_t **bytecode, size_t *size, size_t position, hex_item_t *result) { - size_t length = 0; - int shift = 0; - - // Decode the variable-length integer for the symbol length - do + // Get the index of the symbol (one byte) + if (*size == 0) { - if (*size == 0) - { - hex_error(ctx, "Bytecode size too small to contain a symbol length"); - return 1; - } - length |= ((**bytecode & 0x7F) << shift); - shift += 7; - (*bytecode)++; - (*size)--; - } while (**bytecode & 0x80); + hex_error(ctx, "Bytecode size too small to contain a symbol length"); + return 1; + } + size_t index = **bytecode; + (*bytecode)++; + (*size)--; - if (*size < length) + if (index >= ctx->symbol_table.count) { - hex_error(ctx, "Bytecode size too small to contain the symbol"); + hex_error(ctx, "Symbol index out of bounds"); return 1; } + char *value = hex_symboltable_get_value(ctx, index); + size_t length = strlen(value); - char *value = (char *)malloc(length + 1); if (!value) { hex_error(ctx, "Memory allocation failed"); return 1; } - memcpy(value, *bytecode, length); - value[length] = '\0'; - *bytecode += length; - *size -= length; + + *bytecode += 1; + *size -= 1; hex_token_t *token = (hex_token_t *)malloc(sizeof(hex_token_t)); + token->value = (char *)malloc(length + 1); strncpy(token->value, value, length + 1); token->position.line = 0;@@ -876,7 +868,6 @@ item.type = HEX_TYPE_USER_SYMBOL;
item.token = token; hex_debug(ctx, "LOOKUP[%zu]: %s", length, value); - free(value); *result = item; return 0; }@@ -970,8 +961,14 @@ {
size_t bytecode_size = size; size_t position = bytecode_size; uint8_t header[8]; + if (size < 8) + { + hex_error(ctx, "Bytecode size too small to contain a header"); + return 1; + } memcpy(header, bytecode, 8); int symbol_table_size = hex_validate_header(header); + hex_debug(ctx, "hex executable file - version: %d - symbols: %d", header[4], symbol_table_size); if (symbol_table_size < 0) { hex_error(ctx, "Invalid bytecode header");@@ -982,9 +979,11 @@ size -= 8;
// Extract the symbol table if (symbol_table_size > 0) { - hex_decode_bytecode_symboltable(ctx, bytecode, symbol_table_size); - bytecode += symbol_table_size; - size -= symbol_table_size; + if (hex_decode_bytecode_symboltable(ctx, &bytecode, &size, symbol_table_size) != 0) + { + hex_error(ctx, "Failed to decode the symbol table"); + return 1; + } } // Debug: Print all symbols in the symbol table hex_debug(ctx, "Symbol Table:");@@ -996,7 +995,7 @@ while (size > 0)
{ position = bytecode_size - size; uint8_t opcode = *bytecode; - hex_debug(ctx, "Bytecode Position: %zu - opcode: %u", position, opcode); + hex_debug(ctx, "Bytecode Position: %zu - opcode: %02X", position, opcode); bytecode++; size--;