// Hash map which maps string -> int use fmt; use hash::fnv; def BUCKETS: size = 64; type hashmap = [BUCKETS][](str, int); fn getitem(map: *hashmap, key: str) (int | void) = { let bucket = &map[fnv::string(key) % len(map)]; for (let i = 0z; i < len(bucket); i += 1) { if (bucket[i].0 == key) { return bucket[i].1; }; }; }; fn setitem(map: *hashmap, key: str, value: int) void = { let bucket = &map[fnv::string(key) % len(map)]; for (let i = 0z; i < len(bucket); i += 1) { if (bucket[i].0 == key) { bucket[i].1 = value; return; }; }; append(bucket, (key, value)); }; fn delitem(map: *hashmap, key: str) (int | void) = { let bucket = &map[fnv::string(key) % len(map)]; for (let i = 0z; i < len(bucket); i += 1) { if (bucket[i].0 == key) { let item = bucket[i]; delete(bucket[i]); return item.1; }; }; }; fn finish(map: *hashmap) void = { for (let i = 0z; i < len(map); i += 1) { free(map[i]); }; }; export fn main() void = { let map: hashmap = [[]...]; defer finish(&map); setitem(&map, "hello", 1234); setitem(&map, "world!", 4321); assert(getitem(&map, "hello") as int == 1234); assert(getitem(&map, "world!") as int == 4321); assert(getitem(&map, "hi there") is void); assert(delitem(&map, "hello") as int == 1234); // Enumerate keys/values for (let i = 0z; i < len(map); i += 1) { for (let j = 0z; j < len(map[i]); j += 1) { let item = &map[i][j]; fmt::printfln("{}: {}", item.0, item.1)!; }; }; };