Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved math of lua #12

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
73 changes: 73 additions & 0 deletions lmathlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
** See Copyright Notice in lua.h
*/

/*
* Tarptaeya modified mathematical library for lua
*/

#define lmathlib_c
#define LUA_LIB

Expand Down Expand Up @@ -37,6 +41,8 @@


static int math_abs (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.abs takes exactly one parameter");
if (lua_isinteger(L, 1)) {
lua_Integer n = lua_tointeger(L, 1);
if (n < 0) n = (lua_Integer)(0u - (lua_Unsigned)n);
Expand All @@ -47,32 +53,64 @@ static int math_abs (lua_State *L) {
return 1;
}

static int math_gcd(lua_State* L) { /* iterative euclid algorithm for gcd of two integers */
int n = lua_gettop(L);
luaL_argcheck(L, n == 2, 1, "math.gcd takes exactly two arguments");
if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
lua_Integer a = lua_tointeger(L, 1);
lua_Integer b = lua_tointeger(L, 2);
if (a == 0) lua_pushnumber(L, a);
else {
while (b != 0) {
if (a > b) a = a - b;
else b = b - a;
}
lua_pushnumber(L, (lua_Integer)a);
}
} else {
// TODO : generate a error for arguments not being integer
}
return 1;
}

static int math_sin (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.sin takes exactly one argument");
lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
return 1;
}

static int math_cos (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.cos takes exactly one argument");
lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
return 1;
}

static int math_tan (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.tan takes exactly one argument");
lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
return 1;
}

static int math_asin (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.asin takes exactly one argument");
lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
return 1;
}

static int math_acos (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.acos takes exactly one argument");
lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
return 1;
}

static int math_atan (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, 2 >= n >= 1, 1, "math.exp takes either one or two argument(s)");
lua_Number y = luaL_checknumber(L, 1);
lua_Number x = luaL_optnumber(L, 2, 1);
lua_pushnumber(L, l_mathop(atan2)(y, x));
Expand All @@ -81,6 +119,7 @@ static int math_atan (lua_State *L) {


static int math_toint (lua_State *L) {
// TODO radix to convert to integer
int valid;
lua_Integer n = lua_tointegerx(L, 1, &valid);
if (valid)
Expand All @@ -103,6 +142,8 @@ static void pushnumint (lua_State *L, lua_Number d) {


static int math_floor (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.floor takes exactly one argument");
if (lua_isinteger(L, 1))
lua_settop(L, 1); /* integer is its own floor */
else {
Expand All @@ -114,6 +155,8 @@ static int math_floor (lua_State *L) {


static int math_ceil (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.ceil takes exactly one argument");
if (lua_isinteger(L, 1))
lua_settop(L, 1); /* integer is its own ceil */
else {
Expand All @@ -125,6 +168,8 @@ static int math_ceil (lua_State *L) {


static int math_fmod (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 2, 1, "math.exp takes exactly two arguments");
if (lua_isinteger(L, 1) && lua_isinteger(L, 2)) {
lua_Integer d = lua_tointeger(L, 2);
if ((lua_Unsigned)d + 1u <= 1u) { /* special cases: -1 or 0 */
Expand All @@ -147,6 +192,8 @@ static int math_fmod (lua_State *L) {
** 'double'.
*/
static int math_modf (lua_State *L) {
int n_ = lua_gettop(L);
luaL_argcheck(L, n_ == 1, 1, "math.modf takes exactly two argument");
if (lua_isinteger(L ,1)) {
lua_settop(L, 1); /* number is its own integer part */
lua_pushnumber(L, 0); /* no fractional part */
Expand All @@ -164,19 +211,25 @@ static int math_modf (lua_State *L) {


static int math_sqrt (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.sqrt takes exactly one argument");
lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
return 1;
}


static int math_ult (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.ult takes exactly two arguments");
lua_Integer a = luaL_checkinteger(L, 1);
lua_Integer b = luaL_checkinteger(L, 2);
lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
return 1;
}

static int math_log (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, 2 >= n >= 1, 1, "math.log takes either one or two arguments");
lua_Number x = luaL_checknumber(L, 1);
lua_Number res;
if (lua_isnoneornil(L, 2))
Expand All @@ -197,16 +250,22 @@ static int math_log (lua_State *L) {
}

static int math_exp (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.exp takes exactly one argument");
lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
return 1;
}

static int math_deg (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.deg takes exactly one argument");
lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
return 1;
}

static int math_rad (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.rad takes exactly one argument");
lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
return 1;
}
Expand Down Expand Up @@ -304,21 +363,30 @@ static int math_type (lua_State *L) {
#if defined(LUA_COMPAT_MATHLIB)

static int math_cosh (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.cosh takes exactly one argument");
lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
return 1;
}

static int math_sinh (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.sinh takes exactly one argument");
lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
return 1;
}

static int math_tanh (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.tan takes exactly one argument");
lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
return 1;
}

static int math_pow (lua_State *L) {
// TODO : power like in python pow
int n = lua_gettop(L);
luaL_argcheck(L, n == 2, 1, "math.pow takes exactly one argument");
lua_Number x = luaL_checknumber(L, 1);
lua_Number y = luaL_checknumber(L, 2);
lua_pushnumber(L, l_mathop(pow)(x, y));
Expand All @@ -333,13 +401,17 @@ static int math_frexp (lua_State *L) {
}

static int math_ldexp (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 2, 1, "math.ldexp takes exactly one argument");
lua_Number x = luaL_checknumber(L, 1);
int ep = (int)luaL_checkinteger(L, 2);
lua_pushnumber(L, l_mathop(ldexp)(x, ep));
return 1;
}

static int math_log10 (lua_State *L) {
int n = lua_gettop(L);
luaL_argcheck(L, n == 1, 1, "math.log10 takes exactly one argument");
lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
return 1;
}
Expand All @@ -361,6 +433,7 @@ static const luaL_Reg mathlib[] = {
{"tointeger", math_toint},
{"floor", math_floor},
{"fmod", math_fmod},
{"gcd", math_gcd},
{"ult", math_ult},
{"log", math_log},
{"max", math_max},
Expand Down