Last active
December 18, 2019 08:49
-
-
Save CaptainPRICE/130714c883544c972ae560cb2f429592 to your computer and use it in GitHub Desktop.
struct int32 for Lua.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local math = math | |
local math_floor = math.floor | |
local error, setmetatable, rawget, tostring, type = error, setmetatable, rawget, tostring, type | |
int = {} | |
do | |
local INT32, INT32_NAME, INT32_SIZE, INT32_DEFAULT, INT32_MAX, INT32_MIN = 3, "int32", 32, 0, 2147483648, -2147483648 | |
local int32 = { | |
__metatable = false, | |
__name = INT32_NAME, | |
__newindex = function(_, _, _) end, | |
__size = INT32_SIZE, | |
__type = INT32 | |
} | |
int32.__index = int32 | |
local isint32 = function(t) | |
return type(t) == "table" and type(t.__type) == "number" and t.__type == INT32 and type(t.__name) == "string" and t.__name == INT32_NAME and type(t.__size) == "number" and t.__size == INT32_SIZE and type(t.value) == "number" | |
end | |
local int32_wrap = function(i) | |
if i < INT32_MIN then | |
return INT32_MAX - (INT32_MIN - i) % (INT32_MAX - INT32_MIN) | |
end | |
return INT32_MIN + (i - INT32_MIN) % (INT32_MAX - INT32_MIN) | |
end | |
local new = function(i) | |
if i then | |
if isint32(i) then | |
i = i.value | |
elseif type(i) ~= "number" then | |
return error("New: wrong argument type (<" .. INT32_NAME .. "/number> expected)") | |
end | |
end | |
return setmetatable({ value = i and int32_wrap(math_floor(i)) or INT32_DEFAULT }, int32) | |
end | |
local zero = new(0) | |
function int32.__unm(n) | |
if isint32(n) then | |
return new(-n.value) | |
end | |
return error("Unm: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__add(l, r) | |
if isint32(l) and isint32(r) then | |
return new(l.value + r.value) | |
end | |
return error("Add: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__sub(l, r) | |
if isint32(l) and isint32(r) then | |
return new(l.value - r.value) | |
end | |
return error("Sub: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__mul(l, r) | |
if isint32(l) and isint32(r) then | |
return new(l.value * r.value) | |
end | |
return error("Mul: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__div(l, r) | |
if isint32(l) and isint32(r) then | |
return new(l.value / r.value) | |
end | |
return error("Div: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__mod(l, r) | |
if isint32(l) and isint32(r) then | |
return new(l.value % r.value) | |
end | |
return error("Mod: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__pow(l, r) | |
if isint32(l) and isint32(r) then | |
return new(l.value ^ r.value) | |
end | |
return error("Pow: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__eq(l, r) | |
return l.value == r.value | |
end | |
function int32.__lt(l, r) | |
return l.value < r.value | |
end | |
function int32.__le(l, r) | |
return l.value <= r.value | |
end | |
function int32.__concat(l, r) | |
if isint32(l) then | |
return tostring(l.value) .. tostring(r) | |
end | |
if isint32(r) then | |
return tostring(l) .. tostring(r.value) | |
end | |
return error("Concat: wrong argument types (<" .. INT32_NAME .. "> expected)") | |
end | |
function int32.__tostring(self) | |
return tostring(self.value) | |
end | |
int = setmetatable( | |
{ new = new, isint32 = isint32, zero = zero, MaxValue = INT32_MAX - 1, MinValue = INT32_MIN }, | |
{ | |
__call = function(_, i) return new(i) end, | |
__newindex = function(_, _, _) end, | |
__index = function(self, k) | |
if k == "new" or k == "isint32" or k == "zero" then | |
return rawget(self, k) | |
end | |
return nil | |
end, | |
__metatable = false | |
} | |
) | |
end | |
local int = int --return int | |
--------------------------------------------------------------------------------------------------- | |
math.randomseed(-6666) | |
print((int)(12345678) == (int)(12345678)) | |
print("my lucky number is " .. (int)(math.random(0, 100))) | |
print("overflow", (int)(123456789123456789123456.789)) | |
print("underflow", (int)(-123456789123456789123456.789)) | |
print((int)((int)(-12345)) == (int)(-12345), (int)(0) == int.zero, int() == (int)(0)) | |
print(int.MinValue < int.MaxValue, int.MaxValue > int.MinValue, (int)(0xDEADBEEF) < (int)(0xBEEF)) | |
--[[ | |
true | |
my lucky number is 34 | |
overflow 2130706432 | |
underflow -2130706432 | |
true true true | |
true true true | |
]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thanks ...