From e476250ea9326b2550847b301c265115ff375a31 Mon Sep 17 00:00:00 2001 From: Sam Atman Date: Wed, 4 Feb 2026 18:36:18 -0500 Subject: Rest of the 'easy' stuff This gets us up to feature parity with Jacob's work. I want to eliminate that last allocation using the comptime hash map, and then see about eliminating allocations from case comparisons as well. That should just about do it. --- src/Scripts.zig | 82 +++++++++++++-------------------------------------------- 1 file changed, 18 insertions(+), 64 deletions(-) (limited to 'src/Scripts.zig') diff --git a/src/Scripts.zig b/src/Scripts.zig index 719b01f..4938318 100644 --- a/src/Scripts.zig +++ b/src/Scripts.zig @@ -1,8 +1,18 @@ //! Scripts Module +const Data = struct { + s1: []const u16 = undefined, + s2: []const u8 = undefined, + s3: []const u8 = undefined, +}; -s1: []u16 = undefined, -s2: []u8 = undefined, -s3: []u8 = undefined, +const scripts = scripts: { + const data = @import("script"); + break :scripts Data{ + .s1 = &data.s1, + .s2 = &data.s2, + .s3 = &data.s3, + }; +}; /// Scripts enum pub const Script = enum { @@ -178,76 +188,20 @@ pub const Script = enum { Yi, Zanabazar_Square, }; -const Scripts = @This(); - -pub fn init(allocator: Allocator) Allocator.Error!Scripts { - var scripts = Scripts{}; - try scripts.setup(allocator); - return scripts; -} - -pub fn setup(scripts: *Scripts, allocator: Allocator) Allocator.Error!void { - scripts.setupInner(allocator) catch |err| { - switch (err) { - error.OutOfMemory => |e| return e, - else => unreachable, - } - }; -} - -inline fn setupInner(scripts: *Scripts, allocator: mem.Allocator) !void { - const in_bytes = @embedFile("scripts"); - var in_fbs = std.io.fixedBufferStream(in_bytes); - var reader = in_fbs.reader(); - - const endian = builtin.cpu.arch.endian(); - - const s1_len: u16 = try reader.readInt(u16, endian); - scripts.s1 = try allocator.alloc(u16, s1_len); - errdefer allocator.free(scripts.s1); - for (0..s1_len) |i| scripts.s1[i] = try reader.readInt(u16, endian); - - const s2_len: u16 = try reader.readInt(u16, endian); - scripts.s2 = try allocator.alloc(u8, s2_len); - errdefer allocator.free(scripts.s2); - _ = try reader.readAll(scripts.s2); - - const s3_len: u16 = try reader.readInt(u8, endian); - scripts.s3 = try allocator.alloc(u8, s3_len); - errdefer allocator.free(scripts.s3); - _ = try reader.readAll(scripts.s3); -} - -pub fn deinit(self: *const Scripts, allocator: mem.Allocator) void { - allocator.free(self.s1); - allocator.free(self.s2); - allocator.free(self.s3); -} /// Lookup the Script type for `cp`. -pub fn script(self: Scripts, cp: u21) ?Script { - const byte = self.s3[self.s2[self.s1[cp >> 8] + (cp & 0xff)]]; +pub fn script(cp: u21) ?Script { + const byte = scripts.s3[scripts.s2[scripts.s1[cp >> 8] + (cp & 0xff)]]; if (byte == 0) return null; return @enumFromInt(byte); } test "script" { - const self = try init(std.testing.allocator); - defer self.deinit(std.testing.allocator); - try testing.expectEqual(Script.Latin, self.script('A').?); -} - -fn testAllocator(allocator: Allocator) !void { - var prop = try Scripts.init(allocator); - prop.deinit(allocator); -} - -test "Allocation failure" { - try testing.checkAllAllocationFailures(testing.allocator, testAllocator, .{}); + try testing.expectEqual(Script.Latin, script('A').?); + // try testing.expectEqual(Script.Deseret, script('𐐌').?); } const std = @import("std"); const builtin = @import("builtin"); -const mem = std.mem; -const Allocator = mem.Allocator; +const unicode = std.unicode; const testing = std.testing; -- cgit v1.2.3