summaryrefslogtreecommitdiff
path: root/dseg.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-08-04 23:52:08 -0400
committerCarson Fleming <cflems@cflems.net>2026-08-04 23:52:08 -0400
commitb6861148021df1682f424d3ce8e8051b80889b03 (patch)
treed36a8dc9853ba7eddd58acf814a1caf9c0e1acfa /dseg.c
parentebe7f44385c4be54afd2993d54ce6352f612f9fa (diff)
downloadccc-b6861148021df1682f424d3ce8e8051b80889b03.tar.gz
unify hashmap type
Diffstat (limited to 'dseg.c')
-rw-r--r--dseg.c95
1 files changed, 23 insertions, 72 deletions
diff --git a/dseg.c b/dseg.c
index 09e18a3..7236b88 100644
--- a/dseg.c
+++ b/dseg.c
@@ -8,35 +8,9 @@
static integral_t string_counter = 0;
-void dseg_init(struct dseg* dseg) {
- dseg->entries = ccc_alloc(DEFAULT_SIZE * sizeof(struct dseg_entry*));
- dseg->cap = DEFAULT_SIZE;
-}
-
-static void dseg_entry_destroy(struct dseg_entry* entry) {
- free(entry->symbol);
-}
-
-void dseg_destroy(struct dseg* dseg) {
- for (integral_t i = 0; i < dseg->cap; i++) {
- if (dseg->entries[i] == NULL) continue;
- dseg_entry_destroy(dseg->entries[i]);
- free(dseg->entries[i]);
- }
- free(dseg->entries);
-}
-
-static inline integral_t advance_hash(
- integral_t hash,
- integral_t val,
- integral_t cap
-) {
- return ((hash << 5) - hash + val) % cap;;
-}
-
static integral_t hash_string(const char* str, integral_t cap) {
integral_t hash = 0, i = 0;
- while (str[i] != 0) hash = advance_hash(hash, str[i++], cap);
+ while (str[i] != 0) ADVANCE_HASH(hash, str[i++], cap);
return hash;
}
@@ -57,6 +31,22 @@ static bool ent_eq(const struct dseg_entry* a, const struct dseg_entry* b) {
DSEG_PANIC("equality function not defined for entry type");
}
+static void ent_destroy(struct dseg_entry* entry) {
+ free(entry->symbol);
+}
+
+void dseg_init(struct hash_map* dseg) {
+ hm_init(
+ dseg,
+ (hm_hash_fn) hash_ent,
+ (hm_eq_fn) ent_eq,
+ (hm_destroy_fn) ent_destroy);
+}
+
+void dseg_destroy(struct hash_map* dseg) {
+ hm_destroy(dseg);
+}
+
static void ent_assign_key(struct dseg_entry* ent) {
switch (ent->type) {
case ENT_STRING:
@@ -70,47 +60,8 @@ static void ent_assign_key(struct dseg_entry* ent) {
}
}
-static struct dseg_entry** dseg_cell(
- const struct dseg* dseg,
- const struct dseg_entry* ent
-) {
- integral_t orig_idx = hash_ent(ent, dseg->cap);
- integral_t idx = orig_idx;
-
- do {
- if (dseg->entries[idx] == NULL || ent_eq(dseg->entries[idx], ent))
- return &dseg->entries[idx];
- } while ((idx = (idx + 1) % dseg->cap) != orig_idx);
- return NULL;
-}
-
-static void rehash_dseg(struct dseg* dseg) {
- struct dseg_entry** old_ents = dseg->entries;
- integral_t old_cap = dseg->cap;
-
- dseg->cap = (dseg->cap + 1) << 1;
- dseg->entries = ccc_alloc(dseg->cap * sizeof(struct dseg_entry*));
-
- for (integral_t i = 0; i < old_cap; i++) {
- if (old_ents[i] == NULL) continue;
- struct dseg_entry** cell = dseg_cell(dseg, old_ents[i]);
- if (cell == NULL) {
- fprintf(stderr, "ccc: data segment rehash failed, likely a bug\n");
- exit(1);
- }
- *cell = old_ents[i];
- }
-
- free(old_ents);
-}
-
-const char* dseg_put(struct dseg* dseg, struct dseg_entry entry) {
- struct dseg_entry** cell = dseg_cell(dseg, &entry);
- while (cell == NULL) {
- rehash_dseg(dseg);
- cell = dseg_cell(dseg, &entry);
- }
-
+const char* dseg_put(struct hash_map* dseg, struct dseg_entry entry) {
+ struct dseg_entry** cell = (struct dseg_entry**) hm_cell_w(dseg, &entry);
if (*cell != NULL) return (*cell)->symbol;
struct dseg_entry* new_ent = ccc_alloc(sizeof(struct dseg_entry));
*cell = new_ent;
@@ -123,7 +74,7 @@ static inline bool is_printable(char c) {
return ' ' <= c && c <= '~';
}
-void emit_string(FILE* outfile, const struct dseg_entry* ent) {
+void emit_string_data(FILE* outfile, const struct dseg_entry* ent) {
const char* str = ent->key.string;
fprintf(outfile, "db ");
for (integral_t i = 0; str[i] != 0;) {
@@ -138,16 +89,16 @@ void emit_string(FILE* outfile, const struct dseg_entry* ent) {
fprintf(outfile, "0x0");
}
-void emit_dseg(FILE* outfile, const struct dseg* dseg) {
+void emit_dseg(FILE* outfile, const struct hash_map* dseg) {
fprintf(outfile, "section .data\n");
for (integral_t i = 0; i < dseg->cap; i++) {
const struct dseg_entry* ent = dseg->entries[i];
- if (dseg->entries[i] == NULL) continue;
+ if (ent == NULL) continue;
fprintf(outfile, "\t%s ", ent->symbol);
switch (ent->type) {
case ENT_STRING:
- emit_string(outfile, ent);
+ emit_string_data(outfile, ent);
break;
}
fprintf(outfile, "\n");