From a4f175ac61a35da989e9e92591d807fd1d5afcd6 Mon Sep 17 00:00:00 2001 From: mehbark Date: Tue, 25 Jun 2024 15:36:33 -0400 Subject: [PATCH] some specialization, not rly faster tho :( --- bf.zig | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/bf.zig b/bf.zig index 0506b5e..a4d68ce 100644 --- a/bf.zig +++ b/bf.zig @@ -23,6 +23,10 @@ const Level1 = union(enum) { loop_start: u24, loop_end: u24, + zero, + find_zero_left, + find_zero_right, + const Self = @This(); fn pointless(self: Self) bool { @@ -54,10 +58,16 @@ const Level1 = union(enum) { .out => |n| try writer.print("OUT {d: >4}", .{n}), .loop_start => |n| try writer.print("JEZ {d:0>4}", .{n}), .loop_end => |n| try writer.print("JNZ {d:0>4}", .{n}), + .zero => try writer.print("ZER ", .{}), + .find_zero_left => try writer.print("FZL ", .{}), + .find_zero_right => try writer.print("FZR ", .{}), } } }; +// mandelbrot.b has 120 instances of [-] which can be replaced with a memory[mp] = 0 +// dang it! gcc -O3 with code generated by dbf2c.b finishes in like 1.4s + // we'll do the discarding of comment chars here fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) { var cur = Level1.nothing(); @@ -67,8 +77,14 @@ fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) { out.deinit(); openers.deinit(); } + var skip: u8 = 0; + + for (src, 0..) |b, i| { + if (skip > 0) { + skip -= 1; + continue; + } - for (src) |b| { switch (b) { '+', '-' => { const n: i8 = if (b == '+') 1 else -1; @@ -92,8 +108,19 @@ fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) { }, '[' => { if (!cur.pointless()) try out.append(cur); - cur = .{ .loop_start = 0 }; - try openers.append(@as(u24, @truncate(out.items.len))); + // bad (what if space yk) + if ((src[i + 1] == '-' or src[i + 1] == '+') and src[i + 2] == ']') { + try out.append(.zero); + skip = 2; + cur = Level1.nothing(); + } else if ((src[i + 1] == '>' or src[i + 1] == '<') and src[i + 2] == ']') { + try out.append(if (src[i + 1] == '>') .find_zero_right else .find_zero_left); + skip = 2; + cur = Level1.nothing(); + } else { + cur = .{ .loop_start = 0 }; + try openers.append(@as(u24, @truncate(out.items.len))); + } }, ']' => { if (!cur.pointless()) try out.append(cur); @@ -203,8 +230,35 @@ test "level 1" { .{ .loop_end = 0 }, }, ); - testLevel1("bla bla - [ ++ ", &[_]Level1{}) catch |err| try testing.expectEqual(err, error.UnclosedOpener); - testLevel1("wow wow += ]", &[_]Level1{}) catch |err| try testing.expectEqual(err, error.UnopenedCloser); + + testLevel1( + "bla bla - [ ++ ", + &[_]Level1{}, + ) catch |err| try testing.expectEqual(err, error.UnclosedOpener); + testLevel1( + "wow wow += ]", + &[_]Level1{}, + ) catch |err| try testing.expectEqual(err, error.UnopenedCloser); + + try testLevel1( + "+++[>>[-]-+]", + &[_]Level1{ + .{ .inc = 3 }, + .{ .loop_start = 4 }, + .{ .shift = 2 }, + .zero, + .{ .loop_end = 1 }, + }, + ); + + try testLevel1( + "[>][<][-]", + &[_]Level1{ + .find_zero_right, + .find_zero_left, + .zero, + }, + ); } pub fn main() !void { @@ -263,6 +317,17 @@ pub fn main() !void { .loop_end => |new_ip| { if (memory[mp] != 0) ip = new_ip; }, + .zero => memory[mp] = 0, + .find_zero_right => { + while (memory[mp] != 0) { + mp +%= 1; + } + }, + .find_zero_left => { + while (memory[mp] != 0) { + mp -%= 1; + } + }, } ip += 1; }