diff options
| author | 2022-08-13 10:38:27 +0200 | |
|---|---|---|
| committer | 2022-08-13 10:38:27 +0200 | |
| commit | 7d4cb5bb96b061ed8708889b75e4d50757d9b3f2 (patch) | |
| tree | b57fdfa2dd7d61b888930d45c5f8f6f873db39ff /src/util.cff | |
| parent | 62132ecc8d032ef251d6b54177414a9ba29e8610 (diff) | |
set template
Diffstat (limited to 'src/util.cff')
| -rw-r--r-- | src/util.cff | 47 |
1 files changed, 7 insertions, 40 deletions
diff --git a/src/util.cff b/src/util.cff index d1c9dc5..70c80b4 100644 --- a/src/util.cff +++ b/src/util.cff @@ -1,4 +1,4 @@ -import "vec.hff"; +import "set.hff"; import "all.hff"; extern fn xmalloc(n usize) *void { @@ -79,43 +79,10 @@ extern fn fatal(P *Parser, loc Loc, fmt *const u8, ...) void { } extern fn internstr(s *const u8) *const u8 { - static buf Vec<*const u8> = {}; - static set **const u8 = {}; - static N int = {}; - static count int = {}; - - if set == #null { - set = xcalloc(N = 16, sizeof int); - } - - if count == N / 2 { - free(set); - set = xcalloc(N *= 2, sizeof int); - vec_each(s, i, buf, - let i = fnv1a_s(FNV1A_INI, s) & (N - 1); - for ;; { - if set[i] == #null { - set[i] = s; - break; - } - i = (i + 1) & (N - 1); - } - ) - } - - let i0 = fnv1a_s(FNV1A_INI, s) & (N - 1); - let i int = i0; - do { - if set[i] == #null { - ++count; - buf->push(xstrdup(s)); - set[i] = buf.dat[buf.len - 1]; - return set[i]; - } else if streq(set[i], s) { - return set[i]; - } - i = (i + 1) & (N - 1); - } while i != i0; - assert(#f, "unreachable"); - + static set Set<*const u8, struct { + fn hash(s *const u8) u32 { return fnv1a_s(FNV1A_INI, s); } + fn eq(a *const u8, b *const u8) bool { return streq(a, b); } + fn dup(s *const u8) *const u8 { return as(*const u8)xstrdup(s); } + }> = {}; + return *set->intern(s); } |