zig-bf/bf.zig
2024-06-24 13:23:11 -04:00

83 lines
2.4 KiB
Zig

//brainf
const std = @import("std");
const io = std.io;
const fs = std.fs;
const process = std.process;
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
var allocator = arena.allocator();
defer arena.deinit();
var out = io.getStdOut().writer();
var in = io.getStdIn().reader();
var args = process.args();
defer args.deinit();
_ = args.skip();
const prog_path = args.next() orelse {
try io.getStdErr().writer().writeAll("i need a program path :(\n");
process.exit(1);
};
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;
}
}
var mem = try allocator.alloc(u8, 1 << 16);
for (mem) |*m| {
m.* = 0;
}
var mp: u16 = 0;
var ip: u32 = 0;
while (ip < prog_len) {
switch (prog[ip]) {
'+' => mem[mp] +%= 1,
'-' => mem[mp] -%= 1,
'>' => mp +%= 1,
'<' => mp -%= 1,
'[' => {
if (mem[mp] == 0) {
var depth: i16 = 1;
ip += 1;
while (depth > 0) : (ip += 1) {
depth += switch (prog[ip]) {
']' => -1,
'[' => 1,
else => 0,
};
}
ip -= 1;
}
},
']' => {
if (mem[mp] != 0) {
var depth: i16 = 1;
ip -= 1;
while (depth > 0) : (ip -= 1) {
depth += switch (prog[ip]) {
'[' => -1,
']' => 1,
else => 0,
};
}
ip += 1;
}
},
'.' => try out.writeByte(mem[mp]),
',' => mem[mp] = in.readByte() catch 0,
else => unreachable,
}
ip += 1;
}
}