From 89e36db5cb16874878055f33e7c045f46fcd68b4 Mon Sep 17 00:00:00 2001 From: lordlogo2002 Date: Thu, 1 Jan 2026 18:34:04 +0100 Subject: [PATCH] Refactor type definitions: implement immutability and enhance Primitive class functionality --- oop/types.lua | 124 +++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/oop/types.lua b/oop/types.lua index 078b29e..e4a10a1 100644 --- a/oop/types.lua +++ b/oop/types.lua @@ -20,13 +20,57 @@ local function freeze_table(t) }) end -local function IntDef(cls) +local function PrimitiveDef(cls) + function cls._freeze(this) + rawset(this, "__immutable", true) + end + + function cls._thaw(this) + rawset(this, "__immutable", false) + end + + function cls.copy(this) + local cls_ref = getmetatable(this) + local items = rawget(this, "__items") + if items then + return cls_ref(items) + end + return cls_ref(this.value) + end +end + +Types.Primitive = oop.class(PrimitiveDef) +Types.Primitive.__name = "Primitive" + +local function make_primitive(def, name) + local cls = oop.class(def) + cls.__name = name + cls.inherit(Types.Primitive) local base_newindex = cls.__newindex + cls.__newindex = function(self, key, value) + if rawget(self, "__immutable") and key ~= "__fields" then + local mt = getmetatable(self) + local cname = mt and mt.__name or name or "Primitive" + error(cname .. " is immutable", 2) + end + return base_newindex(self, key, value) + end + function cls.__call(this) + local items = rawget(this, "__items") + if items then + return this.items + end + return this.value + end + return cls +end + +local function IntDef(cls) function cls.__init(this, value) - rawset(this, "__frozen", false) + rawset(this, "__immutable", false) this.value = math.floor(tonumber(value) or 0) - rawset(this, "__frozen", true) + rawset(this, "__immutable", true) end function cls.__add(a, b) @@ -59,21 +103,14 @@ local function IntDef(cls) return this.value end - function cls.__newindex(this, key, value) - if rawget(this, "__frozen") and key ~= "__fields" then - error("Int is immutable", 2) - end - return base_newindex(this, key, value) - end end local function FloatDef(cls) - local base_newindex = cls.__newindex function cls.__init(this, value) - rawset(this, "__frozen", false) + rawset(this, "__immutable", false) this.value = tonumber(value) or 0.0 - rawset(this, "__frozen", true) + rawset(this, "__immutable", true) end function cls.__add(a, b) @@ -106,12 +143,6 @@ local function FloatDef(cls) return this.value end - function cls.__newindex(this, key, value) - if rawget(this, "__frozen") and key ~= "__fields" then - error("Float is immutable", 2) - end - return base_newindex(this, key, value) - end end local function ListDef(cls) @@ -198,16 +229,19 @@ local function ListDef(cls) end local function TupleDef(cls) - local base_newindex = cls.__newindex function cls.__init(this, items) - rawset(this, "__frozen", false) + rawset(this, "__immutable", false) if type(items) == "table" then - this.items = freeze_table({ table.unpack(items) }) + local raw_items = { table.unpack(items) } + rawset(this, "__items", raw_items) + this.items = freeze_table(raw_items) else - this.items = freeze_table({}) + local raw_items = {} + rawset(this, "__items", raw_items) + this.items = freeze_table(raw_items) end - rawset(this, "__frozen", true) + rawset(this, "__immutable", true) end function cls.__len(this) @@ -230,12 +264,6 @@ local function TupleDef(cls) return ipairs(this.items) end - function cls.__newindex(this, key, value) - if rawget(this, "__frozen") and key ~= "__fields" then - error("Tuple is immutable", 2) - end - return base_newindex(this, key, value) - end end local function QueueDef(cls) @@ -413,12 +441,11 @@ local function SetDef(cls) end local function BoolDef(cls) - local base_newindex = cls.__newindex function cls.__init(this, value) - rawset(this, "__frozen", false) + rawset(this, "__immutable", false) this.value = not not value - rawset(this, "__frozen", true) + rawset(this, "__immutable", true) end function cls.__tostring(this) @@ -429,21 +456,14 @@ local function BoolDef(cls) return a.value == b.value end - function cls.__newindex(this, key, value) - if rawget(this, "__frozen") and key ~= "__fields" then - error("Bool is immutable", 2) - end - return base_newindex(this, key, value) - end end local function StrDef(cls) - local base_newindex = cls.__newindex function cls.__init(this, value) - rawset(this, "__frozen", false) + rawset(this, "__immutable", false) this.value = tostring(value or "") - rawset(this, "__frozen", true) + rawset(this, "__immutable", true) end function cls.__len(this) @@ -458,25 +478,15 @@ local function StrDef(cls) return this.value end - function cls.__newindex(this, key, value) - if rawget(this, "__frozen") and key ~= "__fields" then - error("Str is immutable", 2) - end - return base_newindex(this, key, value) - end end -Types.Int = oop.class(IntDef) -Types.Int.__name = "Int" - -Types.Float = oop.class(FloatDef) -Types.Float.__name = "Float" +Types.Int = make_primitive(IntDef, "Int") +Types.Float = make_primitive(FloatDef, "Float") Types.List = oop.class(ListDef) Types.List.__name = "List" -Types.Tuple = oop.class(TupleDef) -Types.Tuple.__name = "Tuple" +Types.Tuple = make_primitive(TupleDef, "Tuple") Types.Tupple = Types.Tuple Types.Queue = oop.class(QueueDef) @@ -492,11 +502,9 @@ Types.Dict.__name = "Dict" Types.Set = oop.class(SetDef) Types.Set.__name = "Set" -Types.Bool = oop.class(BoolDef) -Types.Bool.__name = "Bool" +Types.Bool = make_primitive(BoolDef, "Bool") -Types.Str = oop.class(StrDef) -Types.Str.__name = "Str" +Types.Str = make_primitive(StrDef, "Str") Types.String = Types.Str return Types