it WORKS
This commit is contained in:
parent
d2e1b746e2
commit
dac22d0be6
1 changed files with 29 additions and 45 deletions
74
bf.zig
74
bf.zig
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue