81 lines
2.0 KiB
Lua
81 lines
2.0 KiB
Lua
local EType = {}
|
|
EType.__index = EType
|
|
|
|
function EType:__eq(other)
|
|
for k, v in pairs(self) do
|
|
if rawget(other, k) ~= v then
|
|
return false
|
|
end
|
|
end
|
|
for k, v in pairs(other) do
|
|
if rawget(self, k) ~= v then
|
|
return false
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
function EType:__tostring()
|
|
if self.kind == "scalar" then
|
|
return (self.unsigned and "u" or "i") .. self.bits
|
|
elseif self.kind == "func" then
|
|
return (tostring(self.input) .. "->" .. tostring(self.output))
|
|
elseif self.kind == "struct" then
|
|
return ("(" .. table.concat(self.fields, ",") .. ")")
|
|
elseif self.kind == "pointer" then
|
|
return tostring(self.to) .. "*"
|
|
elseif self.kind == "array" then
|
|
return tostring(self.element_etype) .. "[" .. (self.length or "?") .. "]"
|
|
elseif self.kind == "string" then
|
|
return "string"
|
|
end
|
|
error("Unimplemented " .. self.kind)
|
|
end
|
|
|
|
function EType:byte_size()
|
|
if self.kind == "scalar" then
|
|
return (self.bits + 7) // 8
|
|
end
|
|
error("Unimplemented " .. self.kind)
|
|
end
|
|
|
|
local ETypes = {}
|
|
|
|
function ETypes.scalar(unsigned, bits)
|
|
return setmetatable({kind = "scalar", bits = bits, unsigned = unsigned}, EType)
|
|
end
|
|
|
|
function ETypes.func(input_etype, output_etype)
|
|
assert(input_etype ~= nil, "Nil function input")
|
|
assert(output_etype ~= nil, "Nil function output")
|
|
return setmetatable({kind = "func", input = input_etype, output = output_etype, modifiers = {}}, EType)
|
|
end
|
|
|
|
function ETypes.array(element_etype, length)
|
|
return setmetatable({kind = "array", element_etype = element_etype, length = length}, EType)
|
|
end
|
|
|
|
function ETypes.struct(fields)
|
|
return setmetatable({kind = "struct", fields = fields, modifiers = {}}, EType)
|
|
end
|
|
|
|
function ETypes.string()
|
|
return setmetatable({kind = "string"}, EType)
|
|
end
|
|
|
|
function ETypes.ref(child)
|
|
assert(child, "Nil pointee type")
|
|
return setmetatable({kind = "pointer", to = child}, EType)
|
|
end
|
|
|
|
function ETypes.deref(ptr)
|
|
assert(ptr and ptr.kind == "pointer", "Non-pointer type")
|
|
return ptr.to
|
|
end
|
|
|
|
function ETypes.is(etype)
|
|
return type(etype) == "table" and getmetatable(etype) == EType
|
|
end
|
|
|
|
return ETypes
|