obj::instance.zig (2022B)
1 const std = @import("std"); 2 3 const utils = @import("lib::utils.zig"); 4 const table = @import("lib::table.zig"); 5 const hash = @import("hash.zig"); 6 7 const Packed = @import("lib::packed.zig").Packed; 8 const Value = @import("value.zig").Value; 9 const Obj = @import("obj.zig").Obj; 10 const GC = @import("gc.zig").GC; 11 12 pub fn Instance(fields: anytype) type { 13 const Super = Obj(fields); 14 15 return packed struct { 16 const Self = @This(); 17 18 pub const Arg = *Super.Class; 19 pub const Error = error{OutOfMemory}; 20 21 pub const Fields = table.Table(*Super.String, Value, hash.hash_t(*Super.String), Super.String.eql); 22 23 obj: Super, 24 cls: Packed(*Super.Class), 25 fields: Packed(*Fields), 26 bound: Packed(*Super.Class.Methods), 27 28 pub fn init(cls: Arg, allocator: std.mem.Allocator) Error!*Self { 29 const self: *Self = try allocator.create(Self); 30 self.* = Self{ 31 .obj = Super.make(Self), 32 .cls = Packed(*Super.Class).init(cls), 33 .fields = try Packed(*Self.Fields).create(allocator), 34 .bound = try Packed(*Super.Class.Methods).create(allocator), 35 }; 36 return self; 37 } 38 39 pub fn method(self: *Self, gc: *GC, name: *Super.String) !*Super.Function { 40 return self.bound.ptr().get(name) catch 41 switch (try self.cls.ptr().method(name)) { 42 .Static => |sta| sta, 43 .Unbound => |unb| try self.bound.ptr().retset(name, try unb.bind(gc, self)), 44 }; 45 } 46 47 pub fn cast(self: anytype) utils.copy_const(@TypeOf(self), *Super) { 48 return @ptrCast(self); 49 } 50 51 pub fn eql(_: *const Self, _: *const Self) bool { 52 return false; 53 } 54 55 pub fn free(self: *const Self, allocator: std.mem.Allocator) void { 56 self.fields.destroy(allocator); 57 self.bound.destroy(allocator); 58 allocator.destroy(self); 59 } 60 }; 61 }