src/registry.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
#ifndef HEX_H #include "hex.h" #endif //////////////////////////////////////// // Registry Implementation // //////////////////////////////////////// int hex_valid_user_symbol(hex_context_t *ctx, const char *symbol) { // Check that key starts with a letter, or underscore // and subsequent characters (if any) are letters, numbers, or underscores if (strlen(symbol) == 0) { hex_error(ctx, "Symbol name cannot be an empty string"); return 0; } if (!isalpha(symbol[0]) && symbol[0] != '_') { hex_error(ctx, "Invalid symbol: %s", symbol); return 0; } /*if (strlen(symbol) > HEX_MAX_SYMBOL_LENGTH) { hex_error(ctx, "Symbol name too long: %s", symbol); return 0; }*/ for (size_t j = 1; j < strlen(symbol); j++) { if (!isalnum(symbol[j]) && symbol[j] != '_' && symbol[j] != '-') { hex_error(ctx, "Invalid symbol: %s", symbol); return 0; } } return 1; } // Add a symbol to the registry int hex_set_symbol(hex_context_t *ctx, const char *key, hex_item_t *value, int native) { if (!native && hex_valid_user_symbol(ctx, key) == 0) { return 1; } 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->type == HEX_TYPE_NATIVE_SYMBOL) { hex_error(ctx, "[set symbol] Cannot overwrite native symbol '%s'", key); return 1; } free(ctx->registry->entries[i]->key); ctx->registry->entries[i]->key = strdup(key); ctx->registry->entries[i]->value = value; return 0; } } if (ctx->registry->size >= HEX_REGISTRY_SIZE) { hex_error(ctx, "Registry overflow"); hex_free_token(value->token); return 1; } ctx->registry->entries[ctx->registry->size] = malloc(sizeof(hex_registry_entry_t)); if (ctx->registry->entries[ctx->registry->size] == NULL) { hex_error(ctx, "[set symbol] Memory allocation failed for registry entry"); return 1; } ctx->registry->entries[ctx->registry->size]->key = strdup(key); ctx->registry->entries[ctx->registry->size]->value = value; ctx->registry->size++; return 0; } // Register a native symbol void hex_set_native_symbol(hex_context_t *ctx, const char *name, int (*func)()) { hex_item_t *func_item = malloc(sizeof(hex_item_t)); if (func_item == NULL) { hex_error(ctx, "[set native symbol] Memory allocation failed for native symbol '%s'", name); 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); hex_free_item(ctx, func_item); } } // Get a symbol value from the registry int hex_get_symbol(hex_context_t *ctx, const char *key, hex_item_t *result) { 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); 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; } } return 0; } |