Skip to content

Instantly share code, notes, and snippets.

@stevedonovan stevedonovan/lint64.c
Last active May 18, 2016

Embed
What would you like to do?
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)
/*
* 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;
}
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
You can’t perform that action at this time.