1
0
Fork 0

Pass the sanity test

This commit is contained in:
Julien Dessaux 2022-06-09 23:17:53 +02:00
parent aec8f51451
commit 75fc1506e5
Signed by: adyxax
GPG key ID: F92E51B86E07177E
5 changed files with 101 additions and 10 deletions

View file

@ -16,15 +16,13 @@ pub fn decimalInput() IOErrors!i64 {
}
pub fn characterOutput(v: i64) IOErrors!void {
// TODO
_ = v;
return error.NotImplemented;
std.debug.print("{c}", .{@intCast(u8, v)});
return;
}
pub fn decimalOutput(v: i64) IOErrors!void {
// TODO
_ = v;
return error.NotImplemented;
std.debug.print("{d}", .{v});
return;
}
test "all" {

View file

@ -6,7 +6,7 @@ const Line = struct {
data: std.ArrayList(i64),
fn blank(l: *Line, x: i64) void {
const lx = @intCast(i64, l.len());
if (x < l.x or x > l.x + lx) { // outside the field
if (x < l.x or x > l.x + lx - 1) { // outside the field
return;
} else if (x > l.x and x < l.x + lx - 1) { // just set the value
l.data.items[@intCast(usize, x - l.x)] = ' ';

36
src/interpreter.zig Normal file
View file

@ -0,0 +1,36 @@
const std = @import("std");
const field = @import("field.zig");
const pointer = @import("pointer.zig");
pub const Interpreter = struct {
allocator: std.mem.Allocator,
field: *field.Field,
pointer: *pointer.Pointer,
pub fn deinit(self: *Interpreter) void {
self.allocator.destroy(self);
}
pub fn init(allocator: std.mem.Allocator, f: *field.Field, p: *pointer.Pointer) !*Interpreter {
var i = try allocator.create(Interpreter);
errdefer allocator.destroy(i);
i.allocator = allocator;
i.field = f;
i.pointer = p;
return i;
}
pub fn run(self: *Interpreter) !i64 {
while (true) {
if (try self.pointer.exec()) |ret| {
if (ret.code) |code| {
return code;
} else {
return 0;
}
}
}
}
};
test "all" {
std.testing.refAllDecls(@This());
}

View file

@ -1,5 +1,6 @@
const std = @import("std");
const field = @import("field.zig");
const interpreter = @import("interpreter.zig");
const pointer = @import("pointer.zig");
const stackStack = @import("stackStack.zig");
@ -10,3 +11,51 @@ pub fn main() anyerror!void {
test "all" {
std.testing.refAllDecls(@This());
}
test "minimal" {
const minimal = std.io.fixedBufferStream("@").reader();
var f = try field.Field.init(std.testing.allocator);
defer f.deinit();
try f.load(minimal);
const argv = [_][]const u8{"minimal"};
var p = try pointer.Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit();
var i = try interpreter.Interpreter.init(std.testing.allocator, f, p);
defer i.deinit();
var code = try i.run();
try std.testing.expectEqual(code, 0);
}
test "almost minimal" {
const minimal = std.io.fixedBufferStream(" @").reader();
var f = try field.Field.init(std.testing.allocator);
defer f.deinit();
try f.load(minimal);
const argv = [_][]const u8{"minimal"};
var p = try pointer.Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit();
var i = try interpreter.Interpreter.init(std.testing.allocator, f, p);
defer i.deinit();
var code = try i.run();
try std.testing.expectEqual(code, 0);
}
test "sanity" {
var file = try std.fs.cwd().openFile("mycology/sanity.bf", .{});
defer file.close();
var f = try field.Field.init(std.testing.allocator);
defer f.deinit();
try f.load(file.reader());
const argv = [_][]const u8{"sanity"};
var p = try pointer.Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit();
var i = try interpreter.Interpreter.init(std.testing.allocator, f, p);
defer i.deinit();
var code = try i.run();
try std.testing.expectEqual(code, 0);
}

View file

@ -203,11 +203,19 @@ pub const Pointer = struct {
'o' => return error.NotImplemented,
'=' => return error.NotImplemented,
't' => return error.NotImplemented,
else => return error.NotImplemented,
else => if (!p.redirect(c)) {
if (c >= '0' and c <= '9') {
try p.ss.toss.push(c - '0');
} else if (c >= 'a' and c <= 'f') {
try p.ss.toss.push(c - 'a' + 10);
} else {
p.reverse();
}
},
}
return null;
}
fn exec(self: *Pointer) !?pointerReturn {
pub fn exec(self: *Pointer) !?pointerReturn {
// Advances to the next instruction of the field and executes it
// Returns non nil if the pointer terminated, and a return code if
// the program should terminate completely
@ -279,7 +287,7 @@ pub const Pointer = struct {
p.dy = 0;
},
'?' => {
const directions = []i8{ 0, -1, 1, 0, 0, 1, -1, 0 };
const directions = [_]i8{ 0, -1, 1, 0, 0, 1, -1, 0 };
const r = 2 * p.rand.intRangeAtMost(u8, 0, 3);
p.dx = directions[r];
p.dy = directions[r + 1];