1
1
mirror of https://github.com/kanaka/mal.git synced 2024-08-17 09:40:21 +03:00
mal/impls/zig/hmap.zig
Joel Martin 8a19f60386 Move implementations into impls/ dir
- Reorder README to have implementation list after "learning tool"
  bullet.

- This also moves tests/ and libs/ into impls. It would be preferrable
  to have these directories at the top level.  However, this causes
  difficulties with the wasm implementations which need pre-open
  directories and have trouble with paths starting with "../../". So
  in lieu of that, symlink those directories to the top-level.

- Move the run_argv_test.sh script into the tests directory for
  general hygiene.
2020-02-10 23:50:16 -06:00

59 lines
1.8 KiB
Zig

const warn = @import("std").debug.warn;
const Allocator = @import("std").mem.Allocator;
const hash_map = @import("std").hash_map;
const MalType = @import("types.zig").MalType;
const string_eql = @import("utils.zig").string_eql;
const string_copy = @import("utils.zig").string_copy;
const MalError = @import("error.zig").MalError;
fn bad_hash(str: []const u8) u32 {
var hash: u64 = 1;
const m: u32 = (1<<31);
const a: u32 = 1103515245;
const c: u32 = 12345;
var i: usize = 0;
const n = str.len;
while(i < n) {
hash = (hash + str[i]) % m;
hash = (a * hash) % m;
hash = (c + hash) % m;
i += 1;
}
const res: u32 = @intCast(u32, hash % m);
return res;
}
pub const MalHashMap = hash_map.HashMap([]const u8, *MalType, bad_hash, string_eql);
pub fn deepcopy(allocator: *Allocator, hashmap: MalHashMap) MalError!MalHashMap {
var hmap_cpy = MalHashMap.init(allocator);
var iterator = hashmap.iterator();
var optional_pair = iterator.next();
while(true) {
const pair = optional_pair orelse break;
const key = string_copy(allocator, pair.key) catch return MalError.SystemError;
const val = try pair.value.copy(allocator);
_ = hmap_cpy.put(key, val) catch return MalError.SystemError;
optional_pair = iterator.next();
}
return hmap_cpy;
}
pub fn destroy(allocator: *Allocator, hashmap: MalHashMap, shallow: bool) void {
var iterator = hashmap.iterator();
var optional_pair = iterator.next();
while(true) {
const pair = optional_pair orelse break;
//warn(" deleting {} {}\n", pair.key, pair.value);
if(!shallow) {
allocator.free(pair.key);
pair.value.delete(allocator);
}
optional_pair = iterator.next();
}
hashmap.deinit();
}