aboutsummaryrefslogtreecommitdiff
path: root/src/command/generate.zig
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2025-05-20 10:33:45 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2025-05-20 10:33:45 +0200
commit8d45a866497816ade70a0068afd19035a1b769d2 (patch)
tree311c26eacd03d66a0e979efc9cba6c305272be5e /src/command/generate.zig
parentd11b876df07ef2cbdf71f3b509aca19ea45170cf (diff)
rename recognize to benchmark
Diffstat (limited to 'src/command/generate.zig')
-rw-r--r--src/command/generate.zig54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/command/generate.zig b/src/command/generate.zig
new file mode 100644
index 0000000..1d9eb3e
--- /dev/null
+++ b/src/command/generate.zig
@@ -0,0 +1,54 @@
+const std = @import("std");
+const root = @import("root");
+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);
+ }
+}