static int _complex_binary_op1(lua_State *L, ArrayBinaryOperation op) { if (lunum_hasmetatable(L, 1, "array") || lunum_hasmetatable(L, 2, "array")) { return _array_binary_op(L, op); } if (!lunum_hasmetatable(L, 1, "complex")) { lunum_pushcomplex(L, lua_tonumber(L, 1)); lua_replace(L, 1); } if (!lunum_hasmetatable(L, 2, "complex")) { lunum_pushcomplex(L, lua_tonumber(L, 2)); lua_replace(L, 2); } return _complex_binary_op2(L, op); }
void _unary_func(lua_State *L, double(*f)(double), Complex(*g)(Complex), int cast) { if (lua_isnumber(L, 1)) { const double x = lua_tonumber(L, 1); lua_pushnumber(L, f(x)); } else if (lunum_hasmetatable(L, 1, "complex")) { if (g == NULL) { return luaL_error(L, "complex operation not supported"); } const Complex z = lunum_checkcomplex(L, 1); lunum_pushcomplex(L, g(z)); } else if (lunum_hasmetatable(L, 1, "array")) { Array *A = (Array*) lunum_checkarray1(L, 1); if (cast == 0) { Array B = array_new_copy(A, A->dtype); switch (B.dtype) { case ARRAY_TYPE_BOOL : EXPR_EVALF(Bool , B.size, B.data); break; case ARRAY_TYPE_CHAR : EXPR_EVALF(char , B.size, B.data); break; case ARRAY_TYPE_SHORT : EXPR_EVALF(short , B.size, B.data); break; case ARRAY_TYPE_INT : EXPR_EVALF(int , B.size, B.data); break; case ARRAY_TYPE_LONG : EXPR_EVALF(long , B.size, B.data); break; case ARRAY_TYPE_SIZE_T : EXPR_EVALF(size_t , B.size, B.data); break; case ARRAY_TYPE_FLOAT : EXPR_EVALF(float , B.size, B.data); break; case ARRAY_TYPE_DOUBLE : EXPR_EVALF(double , B.size, B.data); break; case ARRAY_TYPE_COMPLEX : EXPR_EVALG(Complex, B.size, B.data); break; } lunum_pusharray1(L, &B); }
void lunum_astable(lua_State *L, int pos) { struct Array *A = lunum_checkarray1(L, pos); const void *a = A->data; lua_newtable(L); for (int i=0; i<A->size; ++i) { lua_pushnumber(L, i+1); switch (A->dtype) { case ARRAY_TYPE_BOOL : lua_pushboolean (L, ((Bool *)a)[i]); break; case ARRAY_TYPE_CHAR : lua_pushnumber (L, ((char *)a)[i]); break; case ARRAY_TYPE_SHORT : lua_pushnumber (L, ((short *)a)[i]); break; case ARRAY_TYPE_INT : lua_pushnumber (L, ((int *)a)[i]); break; case ARRAY_TYPE_LONG : lua_pushnumber (L, ((long *)a)[i]); break; case ARRAY_TYPE_FLOAT : lua_pushnumber (L, ((float *)a)[i]); break; case ARRAY_TYPE_DOUBLE : lua_pushnumber (L, ((double *)a)[i]); break; case ARRAY_TYPE_COMPLEX : lunum_pushcomplex(L, ((Complex *)a)[i]); break; } lua_settable(L, -3); } }
int luaopen_lunum(lua_State *L) { lua_settop(L, 0); // start with an empty stack // Create the 'array' metatable // --------------------------------------------------------------------------- luaL_newmetatable(L, "array"); LUA_NEW_METAMETHOD(L, array, tostring); LUA_NEW_METAMETHOD(L, array, call); LUA_NEW_METAMETHOD(L, array, index); LUA_NEW_METAMETHOD(L, array, newindex); LUA_NEW_METAMETHOD(L, array, add); LUA_NEW_METAMETHOD(L, array, sub); LUA_NEW_METAMETHOD(L, array, mul); LUA_NEW_METAMETHOD(L, array, div); LUA_NEW_METAMETHOD(L, array, idiv); LUA_NEW_METAMETHOD(L, array, mod); LUA_NEW_METAMETHOD(L, array, pow); LUA_NEW_METAMETHOD(L, array, band); LUA_NEW_METAMETHOD(L, array, bor); LUA_NEW_METAMETHOD(L, array, bxor); LUA_NEW_METAMETHOD(L, array, shl); LUA_NEW_METAMETHOD(L, array, shr); LUA_NEW_METAMETHOD(L, array, unm); LUA_NEW_METAMETHOD(L, array, bnot); LUA_NEW_METAMETHOD(L, array, gc); LUA_NEW_METAMETHOD(L, array, preserve); LUA_NEW_METAFUNCTION(L, array, dtype); LUA_NEW_METAFUNCTION(L, array, dtypemin); LUA_NEW_METAFUNCTION(L, array, dtypemax); LUA_NEW_METAFUNCTION(L, array, shape); LUA_NEW_METAFUNCTION(L, array, size); LUA_NEW_METAFUNCTION(L, array, astable); LUA_NEW_METAFUNCTION(L, array, astype); LUA_NEW_METAFUNCTION(L, array, tofile); lua_pop(L, 1); // Create the 'complex' metatable // --------------------------------------------------------------------------- luaL_newmetatable(L, "complex"); LUA_NEW_METAMETHOD(L, complex, tostring); LUA_NEW_METAMETHOD(L, complex, add); LUA_NEW_METAMETHOD(L, complex, sub); LUA_NEW_METAMETHOD(L, complex, mul); LUA_NEW_METAMETHOD(L, complex, div); LUA_NEW_METAMETHOD(L, complex, pow); LUA_NEW_METAMETHOD(L, complex, unm); LUA_NEW_METAMETHOD(L, complex, eq); LUA_NEW_METAMETHOD(L, complex, lt); LUA_NEW_METAMETHOD(L, complex, le); LUA_NEW_METAMETHOD(L, complex, preserve); LUA_NEW_METAFUNCTION(L, complex, new); lua_pop(L, 1); // Create the 'lunum' table // --------------------------------------------------------------------------- lua_newtable(L); LUA_NEW_MODULEMETHOD(L, lunum, array); LUA_NEW_MODULEMETHOD(L, lunum, zeros); LUA_NEW_MODULEMETHOD(L, lunum, range); LUA_NEW_MODULEMETHOD(L, lunum, linear); LUA_NEW_MODULEMETHOD(L, lunum, resize); LUA_NEW_MODULEMETHOD(L, lunum, sin); LUA_NEW_MODULEMETHOD(L, lunum, cos); LUA_NEW_MODULEMETHOD(L, lunum, tan); LUA_NEW_MODULEMETHOD(L, lunum, asin); LUA_NEW_MODULEMETHOD(L, lunum, acos); LUA_NEW_MODULEMETHOD(L, lunum, atan); LUA_NEW_MODULEMETHOD(L, lunum, sinh); LUA_NEW_MODULEMETHOD(L, lunum, cosh); LUA_NEW_MODULEMETHOD(L, lunum, tanh); LUA_NEW_MODULEMETHOD(L, lunum, asinh); LUA_NEW_MODULEMETHOD(L, lunum, acosh); LUA_NEW_MODULEMETHOD(L, lunum, atanh); LUA_NEW_MODULEMETHOD(L, lunum, exp); LUA_NEW_MODULEMETHOD(L, lunum, log); LUA_NEW_MODULEMETHOD(L, lunum, log10); LUA_NEW_MODULEMETHOD(L, lunum, transpose); LUA_NEW_MODULEMETHOD(L, lunum, conjugate); LUA_NEW_MODULEMETHOD(L, lunum, loadtxt); LUA_NEW_MODULEMETHOD(L, lunum, fromfile); LUA_NEW_MODULEMETHOD(L, lunum, slice); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_BOOL , bool); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_CHAR , char); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_SHORT , short); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_INT , int); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_LONG , long); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_SIZE_T , size_t); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_FLOAT , float); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_DOUBLE , double); LUA_NEW_MODULEDATA(L, ARRAY_TYPE_COMPLEX, complex); // Register the purely imaginary number 'I' lunum_pushcomplex(L, I); lua_setfield(L, 1, "I"); lua_setglobal(L, "lunum"); #include "array_class.lc" // sets lunum.__register_array_metafunctions lua_getglobal(L, "lunum"); lua_getfield(L, -1, "__register_array_metafunctions"); luaL_getmetatable(L, "array"); lua_call(L, 1, 0); return 1; }