#include <math.h>
#include "lua.h"
#include "lauxlib.h"
/* get value of Integer userdata or Lua number at index, or die */
static int checkint (lua_State *L, int index) {
if (lua_isuserdata(L, index) && luaL_checkudata(L, index, "integer")) {
return *(int*)lua_touserdata(L, index);
} else if (lua_isnumber(L, index)) {
return lua_tonumber(L, index);
} else {
lua_pushstring(L, "Invalid operand. Expected 'integer' or 'number'");
lua_error(L);
return 0; /* will never get here */
}
}
static int create_integer(lua_State* L, int val) {
int* ud = lua_newuserdata(L, sizeof(int));
*ud = val;
luaL_getmetatable(L, "integer");
lua_setmetatable(L, -2);
return 1;
}
static int int_new (lua_State* L) { return create_integer( L, checkint(L,1) ); }
static int int_add (lua_State* L) { return create_integer( L, checkint(L,1) + checkint(L,2) ); }
static int int_sub (lua_State* L) { return create_integer( L, checkint(L,1) - checkint(L,2) ); }
static int int_mul (lua_State* L) { return create_integer( L, checkint(L,1) * checkint(L,2) ); }
static int int_div (lua_State* L) { return create_integer( L, checkint(L,1) / checkint(L,2) ); }
static int int_mod (lua_State* L) { return create_integer( L, checkint(L,1) % checkint(L,2) ); }
static int int_pow (lua_State* L) { return create_integer( L, pow( checkint(L,1), checkint(L,2) ) ); }
static int int_unm (lua_State* L) { return create_integer( L, -checkint(L,1) ); }
static int int_eq (lua_State* L) { lua_pushboolean( L, checkint(L,1) == checkint(L,2) ); return 1; }
static int int_lt (lua_State* L) { lua_pushboolean( L, checkint(L,1) < checkint(L,2) ); return 1; }
static int int_le (lua_State* L) { lua_pushboolean( L, checkint(L,1) <= checkint(L,2) ); return 1; }
static int int_tostring (lua_State* L) {
lua_pushnumber(L, checkint(L,1));
lua_tostring(L, -1);
return 1;
}
int __declspec(dllexport) __cdecl luaopen_integer (lua_State* L) {
static const struct luaL_reg integermt[] = {
{ "__add", int_add },
{ "__sub", int_sub },
{ "__mul", int_mul },
{ "__div", int_div },
{ "__mod", int_mod },
{ "__pow", int_pow },
{ "__unm", int_unm },
{ "__eq", int_eq },
{ "__lt", int_lt },
{ "__le", int_le },
{ "__tostring", int_tostring},
NULL, NULL
};
luaL_newmetatable(L, "integer");
luaL_openlib(L, NULL, integermt, 0);
lua_register(L, "int", int_new);
return 0;
}