Refactor type definitions: implement immutability and enhance Primitive class functionality

This commit is contained in:
Chipperfluff 2026-01-01 18:34:04 +01:00
parent ec6e7552fc
commit 89e36db5cb

View File

@ -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