aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/field.zig17
-rw-r--r--src/interpreter.zig10
-rw-r--r--src/main.zig59
-rw-r--r--src/pointer.zig6
4 files changed, 37 insertions, 55 deletions
diff --git a/src/field.zig b/src/field.zig
index 1e9b56f..e96a44a 100644
--- a/src/field.zig
+++ b/src/field.zig
@@ -244,8 +244,9 @@ pub const Field = struct {
if (y >= f.y and y < f.y + @intCast(i64, f.lines.items.len)) return f.lines.items[@intCast(usize, y - @intCast(i64, f.y))].get(x);
return ' ';
}
- pub fn init(allocator: std.mem.Allocator) !*Field {
+ fn init(allocator: std.mem.Allocator) !*Field {
var f = try allocator.create(Field);
+ errdefer allocator.destroy(f);
f.allocator = allocator;
f.x = undefined;
f.y = 0;
@@ -255,10 +256,16 @@ pub const Field = struct {
f.lx = 0;
return f;
}
+ pub fn init_from_reader(allocator: std.mem.Allocator, reader: anytype) !*Field {
+ var f = try Field.init(allocator);
+ errdefer f.deinit();
+ try f.load(reader);
+ return f;
+ }
inline fn isIn(f: *Field, x: i64, y: i64) bool {
return x >= f.x and y >= f.y and x < f.x + @intCast(i64, f.lx) and y < f.y + @intCast(i64, f.lines.items.len);
}
- pub fn load(f: *Field, reader: anytype) !void {
+ fn load(f: *Field, reader: anytype) !void {
if (f.lines.items.len > 1 or f.lx > 0) return error.FIELD_NOT_EMPTY;
var lastIsCR = false;
var x: i64 = 0;
@@ -420,9 +427,8 @@ test "all" {
}
test "hello" {
const hello = std.io.fixedBufferStream("64+\"!dlroW ,olleH\">:#,_@\n").reader();
- var f = try Field.init(std.testing.allocator);
+ var f = try Field.init_from_reader(std.testing.allocator, hello);
defer f.deinit();
- try f.load(hello);
try std.testing.expectEqual(f.x, 0);
try std.testing.expectEqual(f.y, 0);
try std.testing.expectEqual(f.lx, 24);
@@ -431,9 +437,8 @@ test "hello" {
}
test "minimal" {
const minimal = std.io.fixedBufferStream("@").reader();
- var f = try Field.init(std.testing.allocator);
+ var f = try Field.init_from_reader(std.testing.allocator, minimal);
defer f.deinit();
- try f.load(minimal);
try std.testing.expectEqual(f.x, 0);
try std.testing.expectEqual(f.y, 0);
try std.testing.expectEqual(f.lx, 1);
diff --git a/src/interpreter.zig b/src/interpreter.zig
index 5702336..1ab07c9 100644
--- a/src/interpreter.zig
+++ b/src/interpreter.zig
@@ -8,14 +8,18 @@ pub const Interpreter = struct {
pointer: *pointer.Pointer,
pub fn deinit(self: *Interpreter) void {
+ self.pointer.deinit();
+ self.field.deinit();
self.allocator.destroy(self);
}
- pub fn init(allocator: std.mem.Allocator, f: *field.Field, p: *pointer.Pointer) !*Interpreter {
+ pub fn init(allocator: std.mem.Allocator, reader: anytype, ioFunctions: ?pointer.IOFunctions, args: []const []const u8) !*Interpreter {
var i = try allocator.create(Interpreter);
errdefer allocator.destroy(i);
i.allocator = allocator;
- i.field = f;
- i.pointer = p;
+ i.field = try field.Field.init_from_reader(allocator, reader);
+ errdefer i.field.deinit();
+ i.pointer = try pointer.Pointer.init(std.testing.allocator, i.field, ioFunctions, args);
+ errdefer i.pointer.deinit();
return i;
}
pub fn run(self: *Interpreter) !i64 {
diff --git a/src/main.zig b/src/main.zig
index 7460c60..3bdf68d 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -5,57 +5,32 @@ const pointer = @import("pointer.zig");
const stackStack = @import("stackStack.zig");
pub fn main() anyerror!void {
- std.log.info("All your codebase are belong to us.", .{});
-}
+ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+ defer std.debug.assert(!gpa.deinit());
+ var args = try std.process.argsAlloc(gpa.allocator());
+ defer std.process.argsFree(gpa.allocator(), args);
+ if (args.len < 2) {
+ std.debug.print("Usage: {s} <b98_file_to_run>\n", .{args[0]});
+ std.os.exit(1);
+ }
-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 file = try std.fs.cwd().openFile("mycology/sanity.bf", .{});
+ defer file.close();
- var i = try interpreter.Interpreter.init(std.testing.allocator, f, p);
+ var i = try interpreter.Interpreter.init(gpa.allocator(), file.reader(), null, args);
defer i.deinit();
- var code = try i.run();
- try std.testing.expectEqual(code, 0);
+ std.os.exit(@intCast(u8, try i.run()));
}
-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 "all" {
+ std.testing.refAllDecls(@This());
}
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);
+ const args = [_][]const u8{"sanity"};
+ var i = try interpreter.Interpreter.init(std.testing.allocator, file.reader(), null, args[0..]);
defer i.deinit();
-
- var code = try i.run();
- try std.testing.expectEqual(code, 0);
+ try std.testing.expectEqual(try i.run(), 0);
}
diff --git a/src/pointer.zig b/src/pointer.zig
index 485a485..62f8dee 100644
--- a/src/pointer.zig
+++ b/src/pointer.zig
@@ -332,9 +332,8 @@ test "all" {
}
test "minimal" {
const minimal = std.io.fixedBufferStream("@").reader();
- var f = try field.Field.init(std.testing.allocator);
+ var f = try field.Field.init_from_reader(std.testing.allocator, minimal);
defer f.deinit();
- try f.load(minimal);
const argv = [_][]const u8{"minimal"};
var p = try Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit();
@@ -342,9 +341,8 @@ test "minimal" {
}
test "almost minimal" {
const minimal = std.io.fixedBufferStream(" @").reader();
- var f = try field.Field.init(std.testing.allocator);
+ var f = try field.Field.init_from_reader(std.testing.allocator, minimal);
defer f.deinit();
- try f.load(minimal);
const argv = [_][]const u8{"minimal"};
var p = try Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit();