This commit is contained in:
mehbark 2024-06-24 23:27:09 -04:00
parent d2e1b746e2
commit dac22d0be6

74
bf.zig
View file

@ -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;
}