From b5bfb6f025ce9dbbbd8353c6a019a0a428f4ddc6 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Sun, 7 Aug 2022 00:09:32 +0200 Subject: Implemented the } (aka end) funge command --- src/pointer.zig | 11 +++++++++-- src/stack.zig | 24 ++++++++++++++++++++++++ src/stackStack.zig | 43 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/pointer.zig b/src/pointer.zig index 70c9a28..7dbf566 100644 --- a/src/pointer.zig +++ b/src/pointer.zig @@ -160,8 +160,15 @@ pub const Pointer = struct { p.sox = p.x + p.dx; p.soy = p.y + p.dy; }, - // TODO - '}' => return error.NotImplemented, + '}' => { + const v = p.ss.end() catch null; + if (v) |so| { + p.sox = so[0]; + p.soy = so[1]; + } else { + p.reverse(); + } + }, // TODO 'u' => return error.NotImplemented, 'g' => { diff --git a/src/stack.zig b/src/stack.zig index 1a70be1..e02cb20 100644 --- a/src/stack.zig +++ b/src/stack.zig @@ -123,6 +123,30 @@ pub const Stack = struct { const fullResult = [_]i64{1}; try std.testing.expectEqualSlices(i64, full.data.items, fullResult[0..]); } + pub fn discard(self: *Stack, n: u64) void { + // Implements a discard mechanism intended for use with the '}'(aka end) stackstack command + if (self.data.items.len > n) { + self.data.items.len -= n; + } else { + self.data.items.len = 0; + } + } + test "discard" { + var empty = try Stack.init(std.testing.allocator); + defer empty.deinit(); + empty.discard(1); + const emptyResult = [_]i64{}; + try std.testing.expectEqualSlices(i64, empty.data.items, emptyResult[0..]); + try empty.push(2); + empty.discard(3); + try std.testing.expectEqualSlices(i64, empty.data.items, emptyResult[0..]); + try empty.push(4); + try empty.push(5); + try empty.push(6); + empty.discard(1); + const emptyResult2 = [_]i64{ 4, 5 }; + try std.testing.expectEqualSlices(i64, empty.data.items, emptyResult2[0..]); + } }; test "all" { diff --git a/src/stackStack.zig b/src/stackStack.zig index 11943a7..208d85a 100644 --- a/src/stackStack.zig +++ b/src/stackStack.zig @@ -25,7 +25,7 @@ pub const StackStack = struct { pub fn begin(self: *StackStack, v: [2]i64) !void { var soss = self.toss; try self.data.append(soss); - var n = soss.pop(); + const n = soss.pop(); self.toss = try stack.Stack.init(self.allocator); if (n > 0) { try self.toss.transfert(soss, @intCast(u64, n)); @@ -78,6 +78,47 @@ pub const StackStack = struct { try std.testing.expectEqualSlices(i64, empty.data.items[2].data.items, sossResult3[0..]); try std.testing.expectEqualSlices(i64, empty.data.items[3].data.items, sossResult4[0..]); } + pub fn end(self: *StackStack) !?[2]i64 { + // Implements the '}' command behaviour which pops a stack from the stack stack + // returns null if a reflect should happen, a storage offset vector otherwise + if (self.data.popOrNull()) |soss| { + const n = self.toss.pop(); + const v = soss.popVector(); + if (n > 0) { + try soss.transfert(self.toss, @intCast(u64, n)); + } else { + soss.discard(@intCast(u64, -n)); + } + self.toss.deinit(); + self.toss = soss; + return v; + } else { + return null; + } + } + test "end" { + var empty = try StackStack.init(std.testing.allocator); + defer empty.deinit(); + try empty.toss.push(1); + try std.testing.expectEqual(empty.end(), null); + const tossResult = [_]i64{1}; + try std.testing.expectEqualSlices(i64, empty.toss.data.items, tossResult[0..]); + try empty.toss.push(2); + try empty.toss.push(3); + try empty.toss.push(4); + try empty.toss.push(2); + try empty.begin([2]i64{ 5, 6 }); + try empty.toss.push(7); + try empty.toss.push(2); + try std.testing.expectEqual(empty.end(), [2]i64{ 5, 6 }); + const tossResult2 = [_]i64{ 1, 2, 4, 7 }; + try std.testing.expectEqualSlices(i64, empty.toss.data.items, tossResult2[0..]); + try empty.toss.push(1); + try empty.begin([2]i64{ 8, 9 }); + try empty.toss.push(-2); + try std.testing.expectEqual(empty.end(), [2]i64{ 8, 9 }); + try std.testing.expectEqualSlices(i64, empty.toss.data.items, tossResult[0..]); + } pub inline fn toss(self: *StackStack) *stack.Stack { return self.toss; } -- cgit v1.2.3