the hito embeddable programming language
at main 84 lines 2.2 kB view raw
1#include "intern.h" 2#include "util.h" 3#include <stdlib.h> 4#include <string.h> 5#include <stdint.h> 6 7 8#define INITIAL_CAPACITY 1024 9 10typedef struct intern_entry intern_entry_t; 11struct intern_entry { 12 const char *str; 13 intern_entry_t *next; 14}; 15 16struct intern_table { 17 size_t capacity; 18 intern_entry_t **buckets; 19}; 20 21intern_table_t *intern_table_alloc(void) { 22 intern_table_t *table = malloc(sizeof(struct intern_table)); 23 if (table == NULL) 24 die("Out of memory: cannot allocate intern table."); 25 26 table->capacity = INITIAL_CAPACITY; 27 table->buckets = calloc(table->capacity, sizeof(intern_entry_t *)); 28 if (table->buckets == NULL) 29 die("Out of memory: cannot allocate intern table buckets."); 30 31 return table; 32} 33 34void intern_table_free(intern_table_t *table) { 35 for (size_t i = 0; i < table->capacity; i++) { 36 intern_entry_t *entry = table->buckets[i]; 37 while (entry != NULL) { 38 intern_entry_t *next = entry->next; 39 free((char *)entry->str); 40 free(entry); 41 entry = next; 42 } 43 } 44 free(table->buckets); 45 free(table); 46} 47 48 49intern_t intern(intern_table_t *table, const char *str) { 50 return intern_prefix(table, str, strlen(str)); 51} 52 53intern_t intern_prefix(intern_table_t *table, const char *str, size_t len) { 54 uint32_t h = hash_buffer(str, len); 55 size_t index = h % table->capacity; 56 for (intern_entry_t *entry = table->buckets[index]; entry != NULL; entry = entry->next) 57 if (strncmp(entry->str, str, len) == 0) 58 return entry->str; 59 60 char *copy = malloc(len + 1); 61 if (copy == NULL) 62 die("Out of memory: cannot allocate interned string"); 63 64 strncpy(copy, str, len); 65 copy[len] = '\0'; 66 intern_entry_t *new_entry = malloc(sizeof(intern_entry_t)); 67 if (new_entry == NULL) 68 die("Out of memory: cannot allocate intern table entry"); 69 70 new_entry->str = copy; 71 new_entry->next = table->buckets[index]; 72 table->buckets[index] = new_entry; 73 return copy; 74} 75 76const char * intern_exists(intern_table_t *table, const char *str) { 77 uint32_t h = hash_string(str); 78 size_t index = h % table->capacity; 79 for (intern_entry_t *entry = table->buckets[index]; 80 entry != NULL; 81 entry = entry->next) if (strcmp(entry->str, str) == 0) 82 return entry->str; 83 return NULL; 84}