some specialization, not rly faster tho :(
This commit is contained in:
parent
dac22d0be6
commit
a4f175ac61
1 changed files with 70 additions and 5 deletions
71
bf.zig
71
bf.zig
|
@ -23,6 +23,10 @@ const Level1 = union(enum) {
|
||||||
loop_start: u24,
|
loop_start: u24,
|
||||||
loop_end: u24,
|
loop_end: u24,
|
||||||
|
|
||||||
|
zero,
|
||||||
|
find_zero_left,
|
||||||
|
find_zero_right,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
fn pointless(self: Self) bool {
|
fn pointless(self: Self) bool {
|
||||||
|
@ -54,10 +58,16 @@ const Level1 = union(enum) {
|
||||||
.out => |n| try writer.print("OUT {d: >4}", .{n}),
|
.out => |n| try writer.print("OUT {d: >4}", .{n}),
|
||||||
.loop_start => |n| try writer.print("JEZ {d:0>4}", .{n}),
|
.loop_start => |n| try writer.print("JEZ {d:0>4}", .{n}),
|
||||||
.loop_end => |n| try writer.print("JNZ {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
|
// we'll do the discarding of comment chars here
|
||||||
fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) {
|
fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) {
|
||||||
var cur = Level1.nothing();
|
var cur = Level1.nothing();
|
||||||
|
@ -67,8 +77,14 @@ fn compileLevel1(allocator: mem.Allocator, src: []const u8) !ArrayList(Level1) {
|
||||||
out.deinit();
|
out.deinit();
|
||||||
openers.deinit();
|
openers.deinit();
|
||||||
}
|
}
|
||||||
|
var skip: u8 = 0;
|
||||||
|
|
||||||
|
for (src, 0..) |b, i| {
|
||||||
|
if (skip > 0) {
|
||||||
|
skip -= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (src) |b| {
|
|
||||||
switch (b) {
|
switch (b) {
|
||||||
'+', '-' => {
|
'+', '-' => {
|
||||||
const n: i8 = if (b == '+') 1 else -1;
|
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);
|
if (!cur.pointless()) try out.append(cur);
|
||||||
|
// 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 };
|
cur = .{ .loop_start = 0 };
|
||||||
try openers.append(@as(u24, @truncate(out.items.len)));
|
try openers.append(@as(u24, @truncate(out.items.len)));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
']' => {
|
']' => {
|
||||||
if (!cur.pointless()) try out.append(cur);
|
if (!cur.pointless()) try out.append(cur);
|
||||||
|
@ -203,8 +230,35 @@ test "level 1" {
|
||||||
.{ .loop_end = 0 },
|
.{ .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 {
|
pub fn main() !void {
|
||||||
|
@ -263,6 +317,17 @@ pub fn main() !void {
|
||||||
.loop_end => |new_ip| {
|
.loop_end => |new_ip| {
|
||||||
if (memory[mp] != 0) ip = 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;
|
ip += 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue