symintern.zig (1014B)
1 const std = @import("std"); 2 3 const Interner = struct { 4 all: std.mem.Allocator, 5 values: std.StringHashMap([]const u8), 6 7 fn init(all: std.mem.Allocator) @This() { 8 return .{ .all = all, .values = std.StringHashMap([]const u8).init(all) }; 9 } 10 11 fn intern(self: *@This(), val: []const u8) ![]const u8 { 12 if (self.values.get(val)) |found| { 13 return found; 14 } else { 15 const copied = try self.all.dupe(u8, val); 16 try self.values.put(copied, copied); 17 18 return copied; 19 } 20 } 21 22 fn deinit(self: *@This()) void { 23 var iter = self.values.valueIterator(); 24 25 while (iter.next()) |val| { 26 self.all.free(val.*); 27 } 28 29 self.values.deinit(); 30 } 31 }; 32 33 var interner: Interner = undefined; 34 35 pub fn init(all: std.mem.Allocator) void { 36 interner = Interner.init(all); 37 } 38 39 pub fn deinit() void { 40 interner.deinit(); 41 } 42 43 pub fn intern(val: []const u8) ![]const u8 { 44 return interner.intern(val); 45 }