diff options
Diffstat (limited to 'identifiers.c')
-rw-r--r-- | identifiers.c | 90 |
1 files changed, 29 insertions, 61 deletions
diff --git a/identifiers.c b/identifiers.c index 52f09b0..a17c002 100644 --- a/identifiers.c +++ b/identifiers.c @@ -28,22 +28,22 @@ static int is_ident(int c) { /* Initialize Identifiers. */ static void idents_create(Identifiers *ids) { - ids->slots = NULL; - ids->nidents = 0; + str_hash_table_create(&ids->table, sizeof(IdentSlot) - sizeof(StrHashTableSlot), NULL); ids->rseed = 0x27182818; } -static U64 ident_hash(char **s) { - U32 x = 0xabcdef01; - U32 y = 0x31415926; - U64 hash = 0; +/* advances s until a non-identifier character is reached, then returns the number of characters advanced */ +static size_t ident_str_len(char **s) { + char *original = *s; while (is_ident(**s)) { - hash += (U64)x * (unsigned char)(**s) + y; - x = rand_u32(x); - y = rand_u32(y); ++*s; } - return hash; + return (size_t)(*s - original); +} + +static U64 ident_hash(char **s) { + char *original = *s; + return str_hash(original, ident_str_len(s)); } /* are these strings equal, up to the first non-ident character? */ @@ -57,7 +57,7 @@ static bool ident_str_eq_str(const char *s, const char *t) { static inline bool ident_eq_str(Identifier i, const char *s) { if (i->anonymous) return false; - return ident_str_eq_str(i->text, s); + return ident_str_eq_str(i->str, s); } @@ -78,55 +78,25 @@ static IdentSlot **ident_slots_insert(IdentSlot **slots, char *s, size_t i) { static Identifier ident_new_anonymous(Identifiers *ids) { U32 idx = rand_u32(ids->rseed); ids->rseed = idx; - IdentSlot **slot = ident_slots_insert(ids->slots, NULL, idx % arr_len(ids->slots)); - *slot = err_calloc(1, sizeof **slot); - ++ids->nidents; - (*slot)->anonymous = true; - (*slot)->len = 3; - (*slot)->text = "???"; - return *slot; + IdentSlot *slot = (IdentSlot *)str_hash_table_insert_anonymous_(&ids->table); + slot->anonymous = true; + return slot; } /* moves s to the char after the identifier */ /* inserts if does not exist. reads until non-ident char is found. */ /* advances past identifier */ static Identifier ident_insert(Identifiers *ids, char **s) { - size_t nslots = arr_len(ids->slots); - if (nslots <= 2*ids->nidents) { - IdentSlot **slots = ids->slots; - /* reserve more space */ - IdentSlot **new_slots = NULL; - size_t new_nslots = nslots * 2 + 10; - arr_set_len(&new_slots, new_nslots); - arr_zero(new_slots); - arr_foreach(slots, IdentSlotPtr, slotp) { - IdentSlot *slot = *slotp; - if (slot) { - char *ptr = slot->text; - U64 new_hash = ident_hash(&ptr); - IdentSlot **new_slot = ident_slots_insert(new_slots, slot->text, new_hash % new_nslots); - *new_slot = slot; - } - } - arr_clear(&slots); - ids->slots = new_slots; - nslots = new_nslots; - } char *original = *s; - U64 hash = ident_hash(s); - IdentSlot **slot = ident_slots_insert(ids->slots, original, hash % arr_len(ids->slots)); - if (!*slot) { - *slot = err_calloc(1, sizeof **slot); - ++ids->nidents; - (*slot)->text = original; - (*slot)->len = (size_t)(*s - original); - } - return *slot; + size_t len = ident_str_len(s); + return (Identifier)str_hash_table_insert_(&ids->table, original, len); } static char *ident_to_str(Identifier i) { char *str = err_malloc(i->len + 1); - /* for some reason, GCC thinks that i->len is -1 when this is called from type_to_str_ (in release mode) */ + /* for some reason, GCC thinks that i->len is -1 when this is called from type_to_str_ (in release mode) + TODO: test this now (some stuff was changed) + */ #if !defined(__clang__) && defined(__GNUC__) #pragma GCC diagnostic push @@ -134,7 +104,7 @@ static char *ident_to_str(Identifier i) { #pragma GCC diagnostic ignored "-Wrestrict" #pragma GCC diagnostic ignored "-Warray-bounds" #endif - memcpy(str, i->text, i->len); + memcpy(str, i->str, i->len); #if !defined(__clang__) && defined(__GNUC__) @@ -146,7 +116,7 @@ static char *ident_to_str(Identifier i) { static void fprint_ident(FILE *out, Identifier id) { - fwrite(id->text, 1, id->len, out); + fwrite(id->str, 1, id->len, out); } static void fprint_ident_debug(FILE *out, Identifier id) { @@ -174,7 +144,7 @@ static void fprint_ident_reduced_charset(FILE *out, Identifier id) { fprintf(out, "a%p__",(void *)id); return; } - for (char *s = id->text; is_ident(*s); ++s) { + for (const char *s = id->str; is_ident(*s); ++s) { int c = (unsigned char)(*s); if (c > 127) { fprintf(out, "x__%x", c); @@ -187,14 +157,13 @@ static void fprint_ident_reduced_charset(FILE *out, Identifier id) { /* NULL = no such identifier. returns identifier "foo" for both "foo\0" and "foo+92384324..." */ static Identifier ident_get(Identifiers *ids, char *s) { char *ptr = s; - U64 hash = ident_hash(&ptr); - IdentSlot **slot = ident_slots_insert(ids->slots, s, hash % arr_len(ids->slots)); - return *slot; + size_t len = ident_str_len(&ptr); + return (Identifier)str_hash_table_get_(&ids->table, s, len); } static Identifier ident_translate(Identifier i, Identifiers *to_idents) { if (!i || i->anonymous) return NULL; - Identifier new_ident = ident_get(to_idents, i->text); + Identifier new_ident = ident_get(to_idents, i->str); return new_ident; } @@ -213,16 +182,15 @@ static IdentDecl *ident_decl(Identifier i) { /* returns true if i and j are equal, even if they're not in the same table */ static bool ident_eq(Identifier i, Identifier j) { - return ident_str_eq_str(i->text, j->text); + return i->len == j->len && memcmp(i->str, j->str, i->len) == 0; } static void idents_free(Identifiers *ids) { - arr_foreach(ids->slots, IdentSlotPtr, slotp) { - IdentSlot *slot = *slotp; + arr_foreach(ids->table.slots, StrHashTableSlotPtr, slotp) { + IdentSlot *slot = *(IdentSlot **)slotp; if (slot) arr_clear(&slot->decls); - free(slot); } - arr_clear(&ids->slots); + str_hash_table_free(&ids->table); } #ifdef TOC_DEBUG |