aboutsummaryrefslogtreecommitdiff
path: root/src/command/generate.zig
blob: 320dbd30d9ef87831d1065622fb4ce0a0174ee6b (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
const std = @import("std");
const root = @import("../main.zig");
const argument = root.argument;
const Generator = root.Generator;
const Scheduler = root.Scheduler;

const GenerateArgs = argument.GenerateArgs;

const RandomGenerator = Generator(struct {
	const Self = @This();

	pub fn next(_: *Self, n: usize) usize {
		return std.crypto.random.uintLessThan(usize, n);
	}
});

fn generate_word(
	args: *GenerateArgs,
	generator: *RandomGenerator,
	allocator: std.mem.Allocator
) []const u8 {
	while (true) {
		const text = generator.sentential_from_grammar(
			&args.grammar,
			10000,
			allocator
		) catch continue;
		if (text.len >= args.min_length) {
			return text;
		}

		allocator.free(text);
	}
}

pub fn generate(args: *GenerateArgs, allocator: std.mem.Allocator) !void {
	var writer = args.output.file.writer();

	var scheduler: Scheduler(generate_word) = undefined;
	try scheduler.init(allocator);
	var generator = RandomGenerator {};

	for (0..args.count) |_| {
		try scheduler.push_task(.{args, &generator, allocator});
	}
	
	const results = try scheduler.deinit();
	defer allocator.free(results);

	for (results) |result| {
		try writer.print("{s}\n", .{result});
		allocator.free(result);
	}
}