1
0
Fork 0

Implemented basic cli

This commit is contained in:
Julien Dessaux 2022-06-12 15:57:54 +02:00
parent 75fc1506e5
commit dc0952685e
Signed by: adyxax
GPG key ID: F92E51B86E07177E
4 changed files with 39 additions and 57 deletions

View file

@ -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); 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 ' '; return ' ';
} }
pub fn init(allocator: std.mem.Allocator) !*Field { fn init(allocator: std.mem.Allocator) !*Field {
var f = try allocator.create(Field); var f = try allocator.create(Field);
errdefer allocator.destroy(f);
f.allocator = allocator; f.allocator = allocator;
f.x = undefined; f.x = undefined;
f.y = 0; f.y = 0;
@ -255,10 +256,16 @@ pub const Field = struct {
f.lx = 0; f.lx = 0;
return f; 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 { 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); 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; if (f.lines.items.len > 1 or f.lx > 0) return error.FIELD_NOT_EMPTY;
var lastIsCR = false; var lastIsCR = false;
var x: i64 = 0; var x: i64 = 0;
@ -420,9 +427,8 @@ test "all" {
} }
test "hello" { test "hello" {
const hello = std.io.fixedBufferStream("64+\"!dlroW ,olleH\">:#,_@\n").reader(); 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(); defer f.deinit();
try f.load(hello);
try std.testing.expectEqual(f.x, 0); try std.testing.expectEqual(f.x, 0);
try std.testing.expectEqual(f.y, 0); try std.testing.expectEqual(f.y, 0);
try std.testing.expectEqual(f.lx, 24); try std.testing.expectEqual(f.lx, 24);
@ -431,9 +437,8 @@ test "hello" {
} }
test "minimal" { test "minimal" {
const minimal = std.io.fixedBufferStream("@").reader(); 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(); defer f.deinit();
try f.load(minimal);
try std.testing.expectEqual(f.x, 0); try std.testing.expectEqual(f.x, 0);
try std.testing.expectEqual(f.y, 0); try std.testing.expectEqual(f.y, 0);
try std.testing.expectEqual(f.lx, 1); try std.testing.expectEqual(f.lx, 1);

View file

@ -8,14 +8,18 @@ pub const Interpreter = struct {
pointer: *pointer.Pointer, pointer: *pointer.Pointer,
pub fn deinit(self: *Interpreter) void { pub fn deinit(self: *Interpreter) void {
self.pointer.deinit();
self.field.deinit();
self.allocator.destroy(self); 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); var i = try allocator.create(Interpreter);
errdefer allocator.destroy(i); errdefer allocator.destroy(i);
i.allocator = allocator; i.allocator = allocator;
i.field = f; i.field = try field.Field.init_from_reader(allocator, reader);
i.pointer = p; errdefer i.field.deinit();
i.pointer = try pointer.Pointer.init(std.testing.allocator, i.field, ioFunctions, args);
errdefer i.pointer.deinit();
return i; return i;
} }
pub fn run(self: *Interpreter) !i64 { pub fn run(self: *Interpreter) !i64 {

View file

@ -5,57 +5,32 @@ const pointer = @import("pointer.zig");
const stackStack = @import("stackStack.zig"); const stackStack = @import("stackStack.zig");
pub fn main() anyerror!void { 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);
}
var file = try std.fs.cwd().openFile("mycology/sanity.bf", .{});
defer file.close();
var i = try interpreter.Interpreter.init(gpa.allocator(), file.reader(), null, args);
defer i.deinit();
std.os.exit(@intCast(u8, try i.run()));
} }
test "all" { test "all" {
std.testing.refAllDecls(@This()); 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" { test "sanity" {
var file = try std.fs.cwd().openFile("mycology/sanity.bf", .{}); var file = try std.fs.cwd().openFile("mycology/sanity.bf", .{});
defer file.close(); defer file.close();
const args = [_][]const u8{"sanity"};
var f = try field.Field.init(std.testing.allocator); var i = try interpreter.Interpreter.init(std.testing.allocator, file.reader(), null, args[0..]);
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(); defer i.deinit();
try std.testing.expectEqual(try i.run(), 0);
var code = try i.run();
try std.testing.expectEqual(code, 0);
} }

View file

@ -332,9 +332,8 @@ test "all" {
} }
test "minimal" { test "minimal" {
const minimal = std.io.fixedBufferStream("@").reader(); 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(); defer f.deinit();
try f.load(minimal);
const argv = [_][]const u8{"minimal"}; const argv = [_][]const u8{"minimal"};
var p = try Pointer.init(std.testing.allocator, f, null, argv[0..]); var p = try Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit(); defer p.deinit();
@ -342,9 +341,8 @@ test "minimal" {
} }
test "almost minimal" { test "almost minimal" {
const minimal = std.io.fixedBufferStream(" @").reader(); 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(); defer f.deinit();
try f.load(minimal);
const argv = [_][]const u8{"minimal"}; const argv = [_][]const u8{"minimal"};
var p = try Pointer.init(std.testing.allocator, f, null, argv[0..]); var p = try Pointer.init(std.testing.allocator, f, null, argv[0..]);
defer p.deinit(); defer p.deinit();