obj::upvalue.zig (1962B)
1 const std = @import("std"); 2 3 const utils = @import("lib::utils.zig"); 4 5 const Packed = @import("lib::packed.zig").Packed; 6 const Value = @import("value.zig").Value; 7 const Obj = @import("obj.zig").Obj; 8 9 pub fn Upvalue(fields: anytype) type { 10 const Super = Obj(fields); 11 12 return packed struct { 13 const Self = @This(); 14 15 pub const Arg = struct { val: *Value, slot: u8, closed: bool = false }; 16 pub const Error = error{OutOfMemory}; 17 18 obj: Super, 19 location: Packed(*Value), 20 closed: bool, 21 slot: u8, 22 23 pub fn init(arg: Arg, allocator: std.mem.Allocator) Error!*Self { 24 const self: *Self = try allocator.create(Self); 25 self.* = Self{ 26 .obj = Super.make(Self), 27 .location = if (arg.closed) 28 try Packed(*Value).create(allocator) 29 else 30 Packed(*Value).init(arg.val), 31 .closed = arg.closed, 32 .slot = arg.slot, 33 }; 34 if (arg.closed) self.location.set(arg.val.*); 35 return self; 36 } 37 38 pub fn close(self: *Self, allocator: std.mem.Allocator) Error!void { 39 if (!self.closed) { 40 const old = self.location.get(); 41 self.location = try Packed(*Value).create(allocator); 42 self.location.set(old); 43 } 44 } 45 46 pub fn cast(self: anytype) utils.copy_const(@TypeOf(self), *Super) { 47 return @ptrCast(self); 48 } 49 50 pub fn format(self: *const Self, writer: *std.Io.Writer) !void { 51 try writer.print("{{{f}:{s}:{d}}}", .{ 52 self.location.get(), 53 if (self.closed) "C" else "O", 54 self.slot, 55 }); 56 } 57 58 pub fn free(self: *const Self, allocator: std.mem.Allocator) void { 59 self.location.destroy(allocator); 60 allocator.destroy(self); 61 } 62 }; 63 }