Last active
May 18, 2016 06:44
-
-
Save stevedonovan/6146474 to your computer and use it in GitHub Desktop.
An int64 module, for Lua 5.1/5,2, by Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>, as extended by Steve Donovan (steve.j.donovan@gmail.com)
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
/* | |
* lint64.c | |
* int64 nummbers for Lua | |
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> | |
* Thu Aug 1 22:56:17 BRT 2013 | |
* This code is hereby placed in the public domain. | |
* Modified by Stevedonovan, Aug 3. | |
* __pow is defined by integer second arg | |
* new can be passed a hex literal string | |
* tohex will return a int64 as a hex string | |
* num will convert a int64 to a Lua number | |
*/ | |
#include <stdlib.h> | |
#if defined(_MSC_VER) | |
#define strtoll _strtoi64 | |
#define EXPORT __declspec(dllexport) | |
#else | |
#define EXPORT | |
#endif | |
#define Int long long | |
#include "lua.h" | |
#include "lauxlib.h" | |
#if LUA_VERSION_NUM == 501 | |
#define luaL_setfuncs(L,funcs,x) luaL_register(L, NULL, funcs) | |
#define luaL_setmetatable(L,t) luaL_getmetatable(L,t); lua_setmetatable(L,-2) | |
#endif | |
#define MYNAME "int64" | |
#define MYTYPE MYNAME | |
#define MYVERSION MYTYPE " library for " LUA_VERSION " / Aug 2013" | |
#define Z(i) Pget(L,i) | |
#define O(i) luaL_optnumber(L,i,0) | |
#define add(z,w) ((z)+(w)) | |
#define sub(z,w) ((z)-(w)) | |
#define mul(z,w) ((z)*(w)) | |
#define div(z,w) ((z)/(w)) | |
#define mod(z,w) ((z)%(w)) | |
#define neg(z) (-(z)) | |
#define new(z) (z) | |
static Int Pget(lua_State *L, int i) | |
{ | |
switch (lua_type(L,i)) | |
{ | |
case LUA_TNUMBER: | |
return luaL_checkint(L,i); | |
case LUA_TSTRING: | |
return strtoll(luaL_checkstring(L,i),NULL,0); | |
default: | |
return *((Int*)luaL_checkudata(L,i,MYTYPE)); | |
} | |
} | |
static int pushInt(lua_State *L, Int z) | |
{ | |
Int *p=lua_newuserdata(L,sizeof(Int)); | |
*p=z; | |
luaL_setmetatable(L,MYTYPE); | |
return 1; | |
} | |
static int Leq(lua_State *L) /** __eq(z,w) */ | |
{ | |
lua_pushboolean(L,Z(1)==Z(2)); | |
return 1; | |
} | |
static int Llt(lua_State *L) /** __lt(z,w) */ | |
{ | |
lua_pushboolean(L,Z(1)<Z(2)); | |
return 1; | |
} | |
static int Ltostring(lua_State *L) /** __tostring(z) */ | |
{ | |
char b[100]; | |
sprintf(b,"%lld",Z(1)); | |
lua_pushstring(L,b); | |
return 1; | |
} | |
static int Ltohex(lua_State *L) /** tohex(z) */ | |
{ | |
char b[100]; | |
sprintf(b,"%llX",Z(1)); | |
lua_pushstring(L,b); | |
return 1; | |
} | |
static int Lnum(lua_State *L) /** num(z) */ | |
{ | |
Int z = Z(1); | |
lua_pushnumber(L,(lua_Number) z); | |
return 1; | |
} | |
static int Lpow(lua_State *L) /** __pow(z,n) */ | |
{ | |
Int res = 1, z = Z(1); | |
int i, n = luaL_checkint(L,2); | |
for (i = 0; i < n; i++) | |
res *= z; | |
return pushInt(L,res); | |
} | |
#define A(f,e) static int L##f(lua_State *L) { return pushInt(L,e); } | |
#define B(f) A(f,f(Z(1),Z(2))) | |
#define F(f) A(f,f(Z(1))) | |
B(add) /** __add(z,w) */ | |
B(div) /** __div(z,w) */ | |
B(mod) /** __mod(z,w) */ | |
B(mul) /** __mul(z,w) */ | |
B(sub) /** __sub(z,w) */ | |
F(neg) /** __unm(z) */ | |
F(new) /** new(z) */ | |
static const luaL_Reg R[] = | |
{ | |
{ "__add", Ladd }, | |
{ "__div", Ldiv }, | |
{ "__eq", Leq }, | |
{ "__lt", Llt }, | |
{ "__mul", Lmul }, | |
{ "__sub", Lsub }, | |
{ "__unm", Lneg }, | |
{ "__pow", Lpow }, | |
{ "__mod", Lmod }, | |
{ "__tostring", Ltostring}, | |
{ "new", Lnew }, | |
{ "tohex", Ltohex }, | |
{ "num", Lnum }, | |
{ NULL, NULL } | |
}; | |
EXPORT int luaopen_int64(lua_State *L) | |
{ | |
if (sizeof(Int)!=8) luaL_error(L,"Int has %d bytes but expected 8",sizeof(Int)); | |
luaL_newmetatable(L,MYTYPE); | |
luaL_setfuncs(L,R,0); | |
lua_pushliteral(L,"version"); /** version */ | |
lua_pushliteral(L,MYVERSION); | |
lua_settable(L,-3); | |
lua_pushliteral(L,"__index"); | |
lua_pushvalue(L,-2); | |
lua_settable(L,-3); | |
return 1; | |
} |
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 int64 = require 'int64' | |
local L = int64.new | |
local hex,num = int64.tohex,int64.num | |
local N = L '0x7FFFFFFFFFFFFFFF' | |
assert(tostring(N),'9223372036854775807') | |
assert(hex(N),'7FFFFFFFFFFFFFFF') | |
assert(hex(L(2)^63 - 1) == '7FFFFFFFFFFFFFFF') | |
assert(num(L(2353)) == 2353) | |
local two = L(2) | |
-- could keep a power-of-two table... | |
local function shift (x,n) | |
return x*two^n | |
end | |
assert(hex(shift(L'0xFF',8))=='FF00') | |
assert(hex(shift(L'0xFF',16))=='FF0000') | |
assert(N % 10 == L(7)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment