DzLox

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

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 }