obj::list.zig (2844B)
1 const std = @import("std"); 2 3 const utils = @import("lib::utils.zig"); 4 const list = @import("lib::list.zig"); 5 6 const Packed = @import("lib::packed.zig").Packed; 7 const Value = @import("value.zig").Value; 8 const Obj = @import("obj.zig").Obj; 9 10 pub fn List(fields: anytype) type { 11 const Super = Obj(fields); 12 13 return packed struct { 14 const Self = @This(); 15 16 pub const List = list.List(Value); 17 pub const Arg = void; 18 pub const Error = error{ OutOfMemory, InvalidArgument } || Self.List.Error; 19 20 obj: Super, 21 list: Packed(*Self.List), 22 23 pub fn init(_: Arg, allocator: std.mem.Allocator) Error!*Self { 24 const self: *Self = try allocator.create(Self); 25 self.* = Self{ 26 .obj = Super.make(Self), 27 .list = try Packed(*Self.List).create(allocator), 28 }; 29 return self; 30 } 31 32 pub fn cast(self: anytype) utils.copy_const(@TypeOf(self), *Super) { 33 return @ptrCast(self); 34 } 35 36 pub fn format(self: *const Self, writer: *std.Io.Writer) std.Io.Writer.Error!void { 37 var lis = self.list.ptr(); 38 var iter = lis.iter(); 39 var count = lis.len(); 40 41 _ = try writer.write("["); 42 while (iter.next()) |val| { 43 count -= 1; 44 try val.format(writer); 45 if (count > 0) _ = try writer.write(", "); 46 } 47 _ = try writer.writeAll("]"); 48 } 49 50 pub fn eql(self: *const Self, other: *const Self) bool { 51 return self.list.ptr().eql(other.list.ptr(), Value.eql); 52 } 53 54 pub fn free(self: *Self, allocator: std.mem.Allocator) void { 55 self.list.destroy(allocator); 56 allocator.destroy(self); 57 } 58 59 pub fn delete(self: *Self, index: Value) void { 60 var lis = self.list.ptr(); 61 if (!index.is(Value.number) or index.number >= @as(Value.tagType(Value.number), @floatFromInt(lis.len()))) { 62 return; 63 } 64 _ = lis.pop(@intFromFloat(index.number)) catch return; 65 } 66 67 pub fn get(self: *const Self, index: Value) Error!Value { 68 var lis = self.list.ptr(); 69 if (!index.is(Value.number) or index.number >= @as(Value.tagType(Value.number), @floatFromInt(lis.len()))) { 70 return Error.InvalidArgument; 71 } 72 return lis.get(@intFromFloat(index.number)); 73 } 74 75 pub fn set(self: *Self, index: Value, val: Value) Error!void { 76 var lis = self.list.ptr(); 77 if (!index.is(Value.number)) { 78 return Error.InvalidArgument; 79 } 80 _ = lis.set(@intFromFloat(index.number), val) catch 81 try lis.push(@intFromFloat(index.number), val); 82 } 83 }; 84 }