aboutsummaryrefslogtreecommitdiff
path: root/src/char-set.zig
blob: d244540bde85fa783125dbf14a1481ed50cd5591 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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;
		}
	}
}