1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// 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)!;
};
};
};