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) { const Level1 = union(enum) {
// think about it... i hope // think about it... i hope
inc: i16, inc: i8,
shift: i16, shift: i16,
// u8 because why would we be reading to/writing from the same cell 256 times in a row // 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) // 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| { for (src) |b| {
switch (b) { switch (b) {
'+', '-' => { '+', '-' => {
const n: i16 = if (b == '+') 1 else -1; const n: i8 = if (b == '+') 1 else -1;
switch (cur) { switch (cur) {
.inc => |*ns| ns.* += n, .inc => |*ns| ns.* +%= n,
else => { else => {
if (!cur.pointless()) try out.append(cur); if (!cur.pointless()) try out.append(cur);
cur = .{ .inc = n }; 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; const n: i16 = if (b == '>') 1 else -1;
switch (cur) { switch (cur) {
.shift => |*ns| ns.* += n, .shift => |*ns| ns.* +%= n,
else => { else => {
if (!cur.pointless()) try out.append(cur); if (!cur.pointless()) try out.append(cur);
cur = .{ .shift = n }; cur = .{ .shift = n };
@ -225,15 +225,10 @@ pub fn main() !void {
}; };
var prog_file = try fs.cwd().openFile(prog_path, .{}); var prog_file = try fs.cwd().openFile(prog_path, .{});
const prog_unfiltered = try prog_file.readToEndAlloc(allocator, 1 << 24); const src = try prog_file.readToEndAlloc(allocator, 1 << 24);
var prog = try allocator.alloc(u8, prog_unfiltered.len); const prog_arr = try compileLevel1(allocator, src);
var prog_len: u32 = 0; const prog = prog_arr.items;
for (prog_unfiltered) |c| { const prog_len = prog.len;
if (c == '+' or c == '-' or c == '>' or c == '<' or c == '[' or c == ']' or c == '.' or c == ',') {
prog[prog_len] = c;
prog_len += 1;
}
}
var memory = try allocator.alloc(u8, 1 << 16); var memory = try allocator.alloc(u8, 1 << 16);
for (memory) |*m| { for (memory) |*m| {
@ -242,43 +237,32 @@ pub fn main() !void {
var mp: u16 = 0; var mp: u16 = 0;
var ip: u32 = 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) { while (ip < prog_len) {
switch (prog[ip]) { switch (prog[ip]) {
'+' => memory[mp] +%= 1, .inc => |n| memory[mp] +%= @bitCast(n),
'-' => memory[mp] -%= 1, .shift => |n| mp +%= @bitCast(n),
'>' => mp +%= 1, .in => |n| {
'<' => mp -%= 1, for (0..(n - 1)) |_| {
'[' => { _ = 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;
} }
memory[mp] = in.readByte() catch 0;
}, },
']' => { .out => |n| {
if (memory[mp] != 0) { try out.writeByteNTimes(memory[mp], n);
var depth: i16 = 1; },
ip -= 1; .loop_start => |new_ip| {
while (depth > 0) : (ip -= 1) { if (memory[mp] == 0) ip = new_ip;
depth += switch (prog[ip]) { },
'[' => -1, .loop_end => |new_ip| {
']' => 1, if (memory[mp] != 0) ip = new_ip;
else => 0,
};
}
ip += 1;
}
}, },
',' => memory[mp] = in.readByte() catch 0,
'.' => try out.writeByte(memory[mp]),
else => unreachable,
} }
ip += 1; ip += 1;
} }