aboutsummaryrefslogtreecommitdiff
path: root/src/util.cff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-13 10:38:27 +0200
committerlemon <lsof@mailbox.org>2022-08-13 10:38:27 +0200
commit7d4cb5bb96b061ed8708889b75e4d50757d9b3f2 (patch)
treeb57fdfa2dd7d61b888930d45c5f8f6f873db39ff /src/util.cff
parent62132ecc8d032ef251d6b54177414a9ba29e8610 (diff)
set template
Diffstat (limited to 'src/util.cff')
-rw-r--r--src/util.cff47
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);
}