# sqstdmath.cpp

    00001 /* see copyright notice in squirrel.h */
    00002 #include <squirrel.h>
    00003 #include <math.h>
    00004 #include <stdlib.h>
    00005 #include <sqstdmath.h>
    00006
    00007 #define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
    00008   SQFloat f; \
    00009   sq_getfloat(v,2,&f); \
    00010   sq_pushfloat(v,(SQFloat)_funcname(f)); \
    00011   return 1; \
    00012 }
    00013
    00014 #define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \
    00015   SQFloat p1,p2; \
    00016   sq_getfloat(v,2,&p1); \
    00017   sq_getfloat(v,3,&p2); \
    00018   sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \
    00019   return 1; \
    00020 }
    00021
    00022 static SQInteger math_srand(HSQUIRRELVM v)
    00023 {
    00024   SQInteger i;
    00025   if(SQ_FAILED(sq_getinteger(v,2,&i)))
    00026     return sq_throwerror(v,_SC("invalid param"));
    00027   srand((unsigned int)i);
    00028   return 0;
    00029 }
    00030
    00031 static SQInteger math_rand(HSQUIRRELVM v)
    00032 {
    00033   sq_pushinteger(v,rand());
    00034   return 1;
    00035 }
    00036
    00037 static SQInteger math_abs(HSQUIRRELVM v)
    00038 {
    00039   SQInteger n;
    00040   sq_getinteger(v,2,&n);
    00041   sq_pushinteger(v,(SQInteger)abs((int)n));
    00042   return 1;
    00043 }
    00044
    00045 SINGLE_ARG_FUNC(sqrt)
    00046 SINGLE_ARG_FUNC(fabs)
    00047 SINGLE_ARG_FUNC(sin)
    00048 SINGLE_ARG_FUNC(cos)
    00049 SINGLE_ARG_FUNC(asin)
    00050 SINGLE_ARG_FUNC(acos)
    00051 SINGLE_ARG_FUNC(log)
    00052 SINGLE_ARG_FUNC(log10)
    00053 SINGLE_ARG_FUNC(tan)
    00054 SINGLE_ARG_FUNC(atan)
    00055 TWO_ARGS_FUNC(atan2)
    00056 TWO_ARGS_FUNC(pow)
    00057 SINGLE_ARG_FUNC(floor)
    00058 SINGLE_ARG_FUNC(ceil)
    00059 SINGLE_ARG_FUNC(exp)
    00060
    00061 #define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck}
    00062 static SQRegFunction mathlib_funcs[] = {
    00063   _DECL_FUNC(sqrt,2,_SC(".n")),
    00064   _DECL_FUNC(sin,2,_SC(".n")),
    00065   _DECL_FUNC(cos,2,_SC(".n")),
    00066   _DECL_FUNC(asin,2,_SC(".n")),
    00067   _DECL_FUNC(acos,2,_SC(".n")),
    00068   _DECL_FUNC(log,2,_SC(".n")),
    00069   _DECL_FUNC(log10,2,_SC(".n")),
    00070   _DECL_FUNC(tan,2,_SC(".n")),
    00071   _DECL_FUNC(atan,2,_SC(".n")),
    00072   _DECL_FUNC(atan2,3,_SC(".nn")),
    00073   _DECL_FUNC(pow,3,_SC(".nn")),
    00074   _DECL_FUNC(floor,2,_SC(".n")),
    00075   _DECL_FUNC(ceil,2,_SC(".n")),
    00076   _DECL_FUNC(exp,2,_SC(".n")),
    00077   _DECL_FUNC(srand,2,_SC(".n")),
    00078   _DECL_FUNC(rand,1,NULL),
    00079   _DECL_FUNC(fabs,2,_SC(".n")),
    00080   _DECL_FUNC(abs,2,_SC(".n")),
    00081   {0,0,0,0},
    00082 };
    00083
    00084 #ifndef M_PI
    00085 #define M_PI (3.14159265358979323846)
    00086 #endif
    00087
    00088 SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
    00089 {
    00090   SQInteger i=0;
    00091   while(mathlib_funcs[i].name!=0) {
    00092     sq_pushstring(v,mathlib_funcs[i].name,-1);
    00093     sq_newclosure(v,mathlib_funcs[i].f,0);
    00094     sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);
    00095     sq_setnativeclosurename(v,-1,mathlib_funcs[i].name);
    00096     sq_createslot(v,-3);
    00097     i++;
    00098   }
    00099   sq_pushstring(v,_SC("RAND_MAX"),-1);
    00100   sq_pushinteger(v,RAND_MAX);
    00101   sq_createslot(v,-3);
    00102   sq_pushstring(v,_SC("PI"),-1);
    00103   sq_pushfloat(v,(SQFloat)M_PI);
    00104   sq_createslot(v,-3);
    00105   return SQ_OK;
    00106 }