aboutsummaryrefslogtreecommitdiff
path: root/src/char-set.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/char-set.zig')
-rw-r--r--src/char-set.zig90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/char-set.zig b/src/char-set.zig
new file mode 100644
index 0000000..d244540
--- /dev/null
+++ b/src/char-set.zig
@@ -0,0 +1,90 @@
+const std = @import("std");
+
+const Character = @import("character.zig").Character;
+
+const Self = @This();
+
+charset: [256]bool = std.mem.zeroes([256]bool),
+
+pub inline fn is_set(self: *const Self, c: usize) bool {
+ return self.charset[c];
+}
+
+pub inline fn set(self: *Self, c: usize) void {
+ self.charset[c] = true;
+}
+
+pub inline fn reset(self: *Self, c: usize) void {
+ self.charset[c] = false;
+}
+
+pub inline fn set_if(self: *Self, c: usize, flag: bool) void {
+ self.charset[c] = self.charset[c] or flag;
+}
+
+pub fn format(
+ self: *const Self,
+ comptime fmt: []const u8,
+ options: std.fmt.FormatOptions,
+ writer: anytype,
+) !void {
+ _ = fmt;
+ _ = options;
+
+ try writer.print("{{ ", .{});
+
+ for (self.charset, 0..) |is_first, index| {
+ if (is_first) {
+ if (index == Character.EPSILON) {
+ try writer.print("{} ", .{Character { .epsilon = void{} }});
+ } else if (index == Character.END) {
+ try writer.print("$ ", .{});
+ } else {
+ try writer.print("'{c}' ", .{@as(u8, @truncate(index))});
+ }
+ }
+ }
+
+ try writer.print("}}", .{});
+}
+
+pub fn expect(self: *const Self, expected: []const u8) !void {
+ var matrix = std.mem.zeroes([255]bool);
+
+ for (expected) |c| {
+ matrix[c] = true;
+ }
+
+ for (matrix, 0..) |contained, index| {
+ if (self.is_set(index) != contained) {
+ std.debug.print("expected {{ ", .{});
+
+ for (expected) |c| {
+ if (c == Character.EPSILON) {
+ std.debug.print("{} ", .{Character { .epsilon = void{} }});
+ } else if (c == Character.END) {
+ std.debug.print("$ ", .{});
+ } else {
+ std.debug.print("'{c}' ", .{c});
+ }
+ }
+
+ std.debug.print("}} but got {} (", .{self});
+
+ if (index == Character.EPSILON) {
+ std.debug.print("{}", .{Character { .epsilon = void{} }});
+ } else if (index == Character.END) {
+ std.debug.print("$", .{});
+ } else {
+ std.debug.print("'{c}'", .{@as(u8, @truncate(index))});
+ }
+ if (contained) {
+ std.debug.print(" missing)\n", .{});
+ } else {
+ std.debug.print(" not expected)\n", .{});
+ }
+
+ return error.ExpectEqualError;
+ }
+ }
+}