DzLox

:)
git clone https://git.sr.ht/~ashymad/DzLox
Log | Files | Refs | Submodules | LICENSE

commit c4e963983d4a234f56bacfb0b0c95e452bee3885
parent b1db7d3cbf3d4f68271b580c4c9adb92f3a766fd
Author: Szymon Mikulicz <szymon.mikulicz@aptiv.com>
Date:   Mon,  9 Sep 2024 15:09:44 +0200

Add for_each to list

Diffstat:
Mzlox/src/list.zig | 39++++++++++++++++++++-------------------
Mzlox/src/obj/list.zig | 31+++++++++++++++++++++----------
2 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/zlox/src/list.zig b/zlox/src/list.zig @@ -74,16 +74,18 @@ pub fn List(T: type) type { } } - fn _set(self: *Self, index: usize, val: ?T) Error!void { + fn _set(self: *Self, index: usize, val: ?T) Error!bool { var idx_rev: isize = @intCast(index); var idx: isize = @as(isize, @intCast(self.len)) - idx_rev; idx_rev += 1; + var isNewVal = false; if (idx <= 0) { while(idx < 0) : (idx += 1) { try self._push(null); } try self._push(val); + isNewVal = true; } else if (idx < idx_rev) { var tip = self.tip; while(idx > 1) : (idx -= 1) { @@ -97,10 +99,10 @@ pub fn List(T: type) type { } end.?.val = val; } - + return isNewVal; } - pub fn set(self: *Self, index: usize, val: T) Error!void { + pub fn set(self: *Self, index: usize, val: T) Error!bool { return self._set(index, val); } @@ -109,7 +111,7 @@ pub fn List(T: type) type { if (index == self.len - 1) { _ = self.pop() catch unreachable; } else { - self._set(index, null) catch unreachable; + _ = self._set(index, null) catch unreachable; } } @@ -141,21 +143,6 @@ pub fn List(T: type) type { try self.push_end(val); } - pub fn format(self: *const Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) utils.fn_error(@TypeOf(writer).write)!void { - _ = try writer.write("["); - var end = self.end; - while (end) |el| : (end = el.prev) { - if (el.val) |v| { - try v.format(fmt, options, writer); - } else { - _ = try writer.write("-"); - } - if (el.prev) |_| _ = try writer.write(", "); - } - _ = try writer.writeAll("]"); - } - - fn _pop(self: *Self) Error!?T { if (self.tip) |tip| { if (tip.next) |next| { @@ -215,5 +202,19 @@ pub fn List(T: type) type { pub fn push_end(self: *Self, val: T) Error!void { return self._push_end(val); } + + pub fn for_each(self: *const Self, arg: anytype, fun: fn (@TypeOf(arg), ?T) void) void { + var end = self.end; + while (end) |el| : (end = el.prev) { + fun(arg, el.val); + } + } + + pub fn for_each_try(self: *const Self, arg: anytype, fun: anytype) utils.fn_error(fun)!void { + var end = self.end; + while (end) |el| : (end = el.prev) { + try fun(arg, el.val); + } + } }; } diff --git a/zlox/src/obj/list.zig b/zlox/src/obj/list.zig @@ -34,16 +34,27 @@ pub const List = packed struct { } pub fn format(self: *const Self, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) utils.fn_error(@TypeOf(writer).write)!void { - _ = try writer.write("["); - var end = self.list.end; - while (end) |el| : (end = el.prev) { - if (el.val) |v| { - try v.format(fmt, options, writer); - } else { - _ = try writer.write("-"); + const Printer = struct { + options: std.fmt.FormatOptions, + writer: @TypeOf(writer), + count: usize, + + pub fn print(this: *@This(), val: ?Value) utils.fn_error(@TypeOf(writer).write)!void { + this.count -= 1; + if (val) |v| { + try v.format(fmt, this.options, this.writer); + } else { + _ = try this.writer.write("-"); + } + if (this.count > 0) _ = try this.writer.write(", "); } - if (el.prev) |_| _ = try writer.write(", "); - } + + }; + + var printer = Printer{.options = options, .writer = writer, .count = self.list.len}; + + _ = try writer.write("["); + try self.list.for_each_try(&printer, Printer.print); _ = try writer.writeAll("]"); } @@ -75,6 +86,6 @@ pub const List = packed struct { if (!index.is(Value.number) or index.number < 0) { return Error.InvalidArgument; } - return self.list.set(@intFromFloat(index.number), val); + _ = try self.list.set(@intFromFloat(index.number), val); } };