diff --git a/bf.zig b/bf.zig index 30cee03..0506b5e 100644 --- a/bf.zig +++ b/bf.zig @@ -9,7 +9,7 @@ const ArrayList = std.ArrayList; const Level1 = union(enum) { // think about it... i hope - inc: i16, + inc: i8, shift: i16, // u8 because why would we be reading to/writing from the same cell 256 times in a row // well, might as well use the extra space (union is bigger than its biggest member) @@ -71,9 +71,9 @@ fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) { for (src) |b| { switch (b) { '+', '-' => { - const n: i16 = if (b == '+') 1 else -1; + const n: i8 = if (b == '+') 1 else -1; switch (cur) { - .inc => |*ns| ns.* += n, + .inc => |*ns| ns.* +%= n, else => { if (!cur.pointless()) try out.append(cur); cur = .{ .inc = n }; @@ -83,7 +83,7 @@ fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) { '>', '<' => { const n: i16 = if (b == '>') 1 else -1; switch (cur) { - .shift => |*ns| ns.* += n, + .shift => |*ns| ns.* +%= n, else => { if (!cur.pointless()) try out.append(cur); cur = .{ .shift = n }; @@ -225,15 +225,10 @@ pub fn main() !void { }; var prog_file = try fs.cwd().openFile(prog_path, .{}); - const prog_unfiltered = try prog_file.readToEndAlloc(allocator, 1 << 24); - var prog = try allocator.alloc(u8, prog_unfiltered.len); - var prog_len: u32 = 0; - for (prog_unfiltered) |c| { - if (c == '+' or c == '-' or c == '>' or c == '<' or c == '[' or c == ']' or c == '.' or c == ',') { - prog[prog_len] = c; - prog_len += 1; - } - } + const src = try prog_file.readToEndAlloc(allocator, 1 << 24); + const prog_arr = try compileLevel1(allocator, src); + const prog = prog_arr.items; + const prog_len = prog.len; var memory = try allocator.alloc(u8, 1 << 16); for (memory) |*m| { @@ -242,43 +237,32 @@ pub fn main() !void { var mp: u16 = 0; var ip: u32 = 0; + // should definitely add a command to print the cool asm + // std.debug.print("{s}\n", .{src}); + // for (prog, 0..) |ins, i| { + // std.debug.print("{:0>4}: {}\n", .{ i, ins }); + // } + + // inc shift in out loop_start loop_end while (ip < prog_len) { switch (prog[ip]) { - '+' => memory[mp] +%= 1, - '-' => memory[mp] -%= 1, - '>' => mp +%= 1, - '<' => mp -%= 1, - '[' => { - if (memory[mp] == 0) { - var depth: i16 = 1; - ip += 1; - while (depth > 0) : (ip += 1) { - depth += switch (prog[ip]) { - ']' => -1, - '[' => 1, - else => 0, - }; - } - ip -= 1; + .inc => |n| memory[mp] +%= @bitCast(n), + .shift => |n| mp +%= @bitCast(n), + .in => |n| { + for (0..(n - 1)) |_| { + _ = in.readByte() catch 0; } + memory[mp] = in.readByte() catch 0; }, - ']' => { - if (memory[mp] != 0) { - var depth: i16 = 1; - ip -= 1; - while (depth > 0) : (ip -= 1) { - depth += switch (prog[ip]) { - '[' => -1, - ']' => 1, - else => 0, - }; - } - ip += 1; - } + .out => |n| { + try out.writeByteNTimes(memory[mp], n); + }, + .loop_start => |new_ip| { + if (memory[mp] == 0) ip = new_ip; + }, + .loop_end => |new_ip| { + if (memory[mp] != 0) ip = new_ip; }, - ',' => memory[mp] = in.readByte() catch 0, - '.' => try out.writeByte(memory[mp]), - else => unreachable, } ip += 1; }