diff --git a/src/main.zig b/src/main.zig index d675e38..5bcb860 100644 --- a/src/main.zig +++ b/src/main.zig @@ -19,13 +19,16 @@ pub fn main() !void { const p = try getPrompt(allocator); defer allocator.free(p); + var iteration: u32 = 0; + while (try ln.linenoise(p)) |input| { defer allocator.free(input); if (input.len > 0) { + iteration += 1; try ln.history.add(input); const command = try tokenizeCommand(input, allocator); defer allocator.free(command); - if (mathTest(rand, 100)) { + if (try mathTest(rand, 100, iteration)) { _ = runCommand(command, allocator) catch |err| switch (err) { error.FileNotFound => print("mash: {s}: command not found\n", .{command[0]}), error.AccessDenied => print("mash: {s}: Permission denied\n", .{command[0]}), @@ -33,17 +36,17 @@ pub fn main() !void { }; } else { print( - \\\n - \\How can you expect to execute commands without knowing any math???\n - \\\n + \\ + \\How can you expect to execute commands without knowing any math??? + \\ , .{}); } } } } -const Operators = enum { - add, +const Operator = enum(u8) { + add = 0, subtract, multiply, divide, @@ -69,8 +72,18 @@ const Operators = enum { } }; +/// Gets add or subtract for the first three commands. +/// Includes multiplication and division after the first three. +fn getRandOp(rand: Random, iteration: u32) Operator { + if (iteration > 3) { + return rand.enumValue(Operator); + } else { + return @enumFromInt(rand.uintAtMost(u8, 1)); + } +} + /// return true if the user passed, false if the user did not. -fn mathTest(rand: Random, limit: i32) bool { +fn mathTest(rand: Random, limit: i32, iteration: u32) !bool { // const operators = comptime .{ // .{ "+", add }, @@ -80,12 +93,25 @@ fn mathTest(rand: Random, limit: i32) bool { // }; // const ops = StaticStringMap(BinaryOperator).initComptime(operators); // _ = ops; - const op = rand.enumValue(Operators); + const op = getRandOp(rand, iteration); const num1 = rand.intRangeAtMost(i32, 1, limit); const num2 = rand.intRangeAtMost(i32, 1, limit); const answer = op.apply(num1, num2); - print("{d} {s} {d} = {d}\n", .{ num1, op.toString(), num2, answer }); - return true; + var input: i32 = undefined; + + // print("release mode {any}\n", .{std.builtin.mode}); + + if (builtin.mode == .Debug) { + print("Answer: {d}\n", .{answer}); + } + print("{d} {s} {d} = ", .{ num1, op.toString(), num2 }); + + input = readInt(stdin) catch |err| { + print("oops: {any}\n", .{err}); + return err; + }; + + return input == answer; } fn runCommand(command: [][]const u8, allocator: Allocator) !u8 { @@ -123,12 +149,22 @@ fn print(comptime fmt: []const u8, args: anytype) void { stdout.print(fmt, args) catch unreachable; } +fn readInt(reader: anytype) !i32 { + var buf: [1024]u8 = undefined; + const buf2 = try reader.readUntilDelimiter(&buf, '\n'); + return std.fmt.parseInt(i32, buf2, 0); +} + const std = @import("std"); const stdout = std.io.getStdOut().writer(); +const stdin = std.io.getStdIn().reader(); const tokenizeAny = std.mem.tokenizeAny; const process = std.process; const Allocator = std.mem.Allocator; const ArrayList = std.ArrayList; const StaticStringMap = std.static_string_map.StaticStringMap; const Random = std.Random; +const Reader = std.io.Reader; const Linenoise = @import("linenoise").Linenoise; + +const builtin = @import("builtin");