From 05756f9289617e4e5e3b97b3622d5ffbd1aa356d Mon Sep 17 00:00:00 2001 From: lordlogo2002 Date: Thu, 1 Jan 2026 18:07:48 +0100 Subject: [PATCH] Add core type definitions: Int, Float, List, Tuple, Queue, Stack, Dict, Set, Bool, and Str --- oop/types.lua | 439 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 oop/types.lua diff --git a/oop/types.lua b/oop/types.lua new file mode 100644 index 0000000..6fdd12a --- /dev/null +++ b/oop/types.lua @@ -0,0 +1,439 @@ +local oop = require("oop") + +local Types = {} + +local function IntDef(cls) + function cls.__init(this, value) + this.value = math.floor(tonumber(value) or 0) + end + + function cls.__add(a, b) + return Types.Int(a.value + b.value) + end + + function cls.__sub(a, b) + return Types.Int(a.value - b.value) + end + + function cls.__mul(a, b) + if type(a) == "number" then + return Types.Int(a * b.value) + end + if type(b) == "number" then + return Types.Int(a.value * b) + end + return Types.Int(a.value * b.value) + end + + function cls.__eq(a, b) + return a.value == b.value + end + + function cls.__tostring(this) + return tostring(this.value) + end + + function cls.to_number(this) + return this.value + end +end + +local function FloatDef(cls) + function cls.__init(this, value) + this.value = tonumber(value) or 0.0 + end + + function cls.__add(a, b) + return Types.Float(a.value + b.value) + end + + function cls.__sub(a, b) + return Types.Float(a.value - b.value) + end + + function cls.__mul(a, b) + if type(a) == "number" then + return Types.Float(a * b.value) + end + if type(b) == "number" then + return Types.Float(a.value * b) + end + return Types.Float(a.value * b.value) + end + + function cls.__eq(a, b) + return a.value == b.value + end + + function cls.__tostring(this) + return tostring(this.value) + end + + function cls.to_number(this) + return this.value + end +end + +local function ListDef(cls) + function cls.__init(this, items) + this.head = nil + this.tail = nil + this.size = 0 + if type(items) == "table" then + for _, v in ipairs(items) do + this.append(v) + end + end + end + + function cls.__len(this) + return this.size + end + + function cls.__tostring(this) + local parts = {} + local node = this.head + while node do + parts[#parts + 1] = tostring(node.value) + node = node.next + end + return "[" .. table.concat(parts, ", ") .. "]" + end + + function cls.append(this, value) + local node = { value = value, next = nil } + if this.tail then + this.tail.next = node + else + this.head = node + end + this.tail = node + this.size = this.size + 1 + end + + function cls.get(this, index) + if type(index) ~= "number" or index < 1 or index > this.size then + return nil + end + local node = this.head + local i = 1 + while node do + if i == index then + return node.value + end + node = node.next + i = i + 1 + end + return nil + end + + function cls.set(this, index, value) + if type(index) ~= "number" or index < 1 or index > this.size then + return false + end + local node = this.head + local i = 1 + while node do + if i == index then + node.value = value + return true + end + node = node.next + i = i + 1 + end + return false + end + + function cls.iter(this) + local node = this.head + return function() + if not node then + return nil + end + local value = node.value + node = node.next + return value + end + end +end + +local function TupleDef(cls) + local base_newindex = cls.__newindex + + function cls.__init(this, items) + if type(items) == "table" then + this.items = { table.unpack(items) } + else + this.items = {} + end + rawset(this, "__frozen", true) + end + + function cls.__len(this) + return #this.items + end + + function cls.__tostring(this) + local parts = {} + for i, v in ipairs(this.items) do + parts[i] = tostring(v) + end + return "(" .. table.concat(parts, ", ") .. ")" + end + + function cls.get(this, index) + return this.items[index] + end + + function cls.iter(this) + 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) + function cls.__init(this, items) + if type(items) == "table" then + this.items = { table.unpack(items) } + else + this.items = {} + end + this.head = 1 + end + + function cls.__len(this) + return #this.items - this.head + 1 + end + + function cls.__tostring(this) + local parts = {} + for i = this.head, #this.items do + parts[#parts + 1] = tostring(this.items[i]) + end + return "Queue([" .. table.concat(parts, ", ") .. "])" + end + + function cls.enqueue(this, value) + this.items[#this.items + 1] = value + end + + function cls.dequeue(this) + if this.head > #this.items then + return nil + end + local value = this.items[this.head] + this.items[this.head] = nil + this.head = this.head + 1 + if this.head > 32 and this.head > (#this.items / 2) then + local new_items = {} + for i = this.head, #this.items do + new_items[#new_items + 1] = this.items[i] + end + this.items = new_items + this.head = 1 + end + return value + end + + function cls.peek(this) + return this.items[this.head] + end +end + +local function StackDef(cls) + function cls.__init(this, items) + if type(items) == "table" then + this.items = { table.unpack(items) } + else + this.items = {} + end + end + + function cls.__len(this) + return #this.items + end + + function cls.__tostring(this) + local parts = {} + for i, v in ipairs(this.items) do + parts[i] = tostring(v) + end + return "Stack([" .. table.concat(parts, ", ") .. "])" + end + + function cls.push(this, value) + this.items[#this.items + 1] = value + end + + function cls.pop(this) + local n = #this.items + if n == 0 then + return nil + end + local value = this.items[n] + this.items[n] = nil + return value + end + + function cls.peek(this) + return this.items[#this.items] + end +end + +local function DictDef(cls) + function cls.__init(this, items) + if type(items) == "table" then + this.items = items + else + this.items = {} + end + end + + function cls.__len(this) + local count = 0 + for _ in pairs(this.items) do + count = count + 1 + end + return count + end + + function cls.__tostring(this) + local parts = {} + for k, v in pairs(this.items) do + parts[#parts + 1] = tostring(k) .. "=" .. tostring(v) + end + return "Dict({" .. table.concat(parts, ", ") .. "})" + end + + function cls.get(this, key, default) + local val = this.items[key] + if val == nil then + return default + end + return val + end + + function cls.set(this, key, value) + this.items[key] = value + end + + function cls.keys(this) + local keys = {} + for k in pairs(this.items) do + keys[#keys + 1] = k + end + return keys + end +end + +local function SetDef(cls) + function cls.__init(this, items) + this.items = {} + if type(items) == "table" then + for _, v in ipairs(items) do + this.items[v] = true + end + end + end + + function cls.__len(this) + local count = 0 + for _ in pairs(this.items) do + count = count + 1 + end + return count + end + + function cls.__tostring(this) + local parts = {} + for k in pairs(this.items) do + parts[#parts + 1] = tostring(k) + end + return "Set({" .. table.concat(parts, ", ") .. "})" + end + + function cls.add(this, value) + this.items[value] = true + end + + function cls.has(this, value) + return this.items[value] == true + end + + function cls.remove(this, value) + this.items[value] = nil + end +end + +local function BoolDef(cls) + function cls.__init(this, value) + this.value = not not value + end + + function cls.__tostring(this) + return tostring(this.value) + end + + function cls.__eq(a, b) + return a.value == b.value + end +end + +local function StrDef(cls) + function cls.__init(this, value) + this.value = tostring(value or "") + end + + function cls.__len(this) + return #this.value + end + + function cls.__concat(a, b) + return Types.Str(tostring(a) .. tostring(b)) + end + + function cls.__tostring(this) + return this.value + end +end + +Types.Int = oop.class(IntDef) +Types.Int.__name = "Int" + +Types.Float = oop.class(FloatDef) +Types.Float.__name = "Float" + +Types.List = oop.class(ListDef) +Types.List.__name = "List" + +Types.Tuple = oop.class(TupleDef) +Types.Tuple.__name = "Tuple" +Types.Tupple = Types.Tuple + +Types.Queue = oop.class(QueueDef) +Types.Queue.__name = "Queue" +Types.Que = Types.Queue + +Types.Stack = oop.class(StackDef) +Types.Stack.__name = "Stack" + +Types.Dict = oop.class(DictDef) +Types.Dict.__name = "Dict" + +Types.Set = oop.class(SetDef) +Types.Set.__name = "Set" + +Types.Bool = oop.class(BoolDef) +Types.Bool.__name = "Bool" + +Types.Str = oop.class(StrDef) +Types.Str.__name = "Str" +Types.String = Types.Str + +return Types