summaryrefslogtreecommitdiff
path: root/src/Scripts.zig
diff options
context:
space:
mode:
authorGravatar Sam Atman2026-02-04 18:36:18 -0500
committerGravatar Sam Atman2026-02-04 18:36:18 -0500
commite476250ea9326b2550847b301c265115ff375a31 (patch)
treecf627ced47cecce80020b7a1f30aa51852c0c59b /src/Scripts.zig
parentNormalization and case folding (diff)
downloadzg-e476250ea9326b2550847b301c265115ff375a31.tar.gz
zg-e476250ea9326b2550847b301c265115ff375a31.tar.xz
zg-e476250ea9326b2550847b301c265115ff375a31.zip
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.
Diffstat (limited to 'src/Scripts.zig')
-rw-r--r--src/Scripts.zig82
1 files changed, 18 insertions, 64 deletions
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 @@
1//! Scripts Module 1//! Scripts Module
2const Data = struct {
3 s1: []const u16 = undefined,
4 s2: []const u8 = undefined,
5 s3: []const u8 = undefined,
6};
2 7
3s1: []u16 = undefined, 8const scripts = scripts: {
4s2: []u8 = undefined, 9 const data = @import("script");
5s3: []u8 = undefined, 10 break :scripts Data{
11 .s1 = &data.s1,
12 .s2 = &data.s2,
13 .s3 = &data.s3,
14 };
15};
6 16
7/// Scripts enum 17/// Scripts enum
8pub const Script = enum { 18pub const Script = enum {
@@ -178,76 +188,20 @@ pub const Script = enum {
178 Yi, 188 Yi,
179 Zanabazar_Square, 189 Zanabazar_Square,
180}; 190};
181const Scripts = @This();
182
183pub fn init(allocator: Allocator) Allocator.Error!Scripts {
184 var scripts = Scripts{};
185 try scripts.setup(allocator);
186 return scripts;
187}
188
189pub fn setup(scripts: *Scripts, allocator: Allocator) Allocator.Error!void {
190 scripts.setupInner(allocator) catch |err| {
191 switch (err) {
192 error.OutOfMemory => |e| return e,
193 else => unreachable,
194 }
195 };
196}
197
198inline fn setupInner(scripts: *Scripts, allocator: mem.Allocator) !void {
199 const in_bytes = @embedFile("scripts");
200 var in_fbs = std.io.fixedBufferStream(in_bytes);
201 var reader = in_fbs.reader();
202
203 const endian = builtin.cpu.arch.endian();
204
205 const s1_len: u16 = try reader.readInt(u16, endian);
206 scripts.s1 = try allocator.alloc(u16, s1_len);
207 errdefer allocator.free(scripts.s1);
208 for (0..s1_len) |i| scripts.s1[i] = try reader.readInt(u16, endian);
209
210 const s2_len: u16 = try reader.readInt(u16, endian);
211 scripts.s2 = try allocator.alloc(u8, s2_len);
212 errdefer allocator.free(scripts.s2);
213 _ = try reader.readAll(scripts.s2);
214
215 const s3_len: u16 = try reader.readInt(u8, endian);
216 scripts.s3 = try allocator.alloc(u8, s3_len);
217 errdefer allocator.free(scripts.s3);
218 _ = try reader.readAll(scripts.s3);
219}
220
221pub fn deinit(self: *const Scripts, allocator: mem.Allocator) void {
222 allocator.free(self.s1);
223 allocator.free(self.s2);
224 allocator.free(self.s3);
225}
226 191
227/// Lookup the Script type for `cp`. 192/// Lookup the Script type for `cp`.
228pub fn script(self: Scripts, cp: u21) ?Script { 193pub fn script(cp: u21) ?Script {
229 const byte = self.s3[self.s2[self.s1[cp >> 8] + (cp & 0xff)]]; 194 const byte = scripts.s3[scripts.s2[scripts.s1[cp >> 8] + (cp & 0xff)]];
230 if (byte == 0) return null; 195 if (byte == 0) return null;
231 return @enumFromInt(byte); 196 return @enumFromInt(byte);
232} 197}
233 198
234test "script" { 199test "script" {
235 const self = try init(std.testing.allocator); 200 try testing.expectEqual(Script.Latin, script('A').?);
236 defer self.deinit(std.testing.allocator); 201 // try testing.expectEqual(Script.Deseret, script('𐐌').?);
237 try testing.expectEqual(Script.Latin, self.script('A').?);
238}
239
240fn testAllocator(allocator: Allocator) !void {
241 var prop = try Scripts.init(allocator);
242 prop.deinit(allocator);
243}
244
245test "Allocation failure" {
246 try testing.checkAllAllocationFailures(testing.allocator, testAllocator, .{});
247} 202}
248 203
249const std = @import("std"); 204const std = @import("std");
250const builtin = @import("builtin"); 205const builtin = @import("builtin");
251const mem = std.mem; 206const unicode = std.unicode;
252const Allocator = mem.Allocator;
253const testing = std.testing; 207const testing = std.testing;