changed qse_awk_prm_t to include basic math functions

This commit is contained in:
2011-05-18 08:37:51 +00:00
parent a2a474bb34
commit da35a4c6dc
5 changed files with 320 additions and 309 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: std.c 451 2011-05-03 14:00:38Z hyunghwan.chung $
* $Id: std.c 459 2011-05-17 14:37:51Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -127,6 +127,110 @@ static qse_real_t custom_awk_pow (qse_awk_t* awk, qse_real_t x, qse_real_t y)
#endif
}
static qse_real_t custom_awk_sin (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_SINL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return sinl (x);
#elif defined(HAVE_SIN)
return sin (x);
#elif defined(HAVE_SINF)
return sinf (x);
#else
#error ### no sin function available ###
#endif
}
static qse_real_t custom_awk_cos (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_COSL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return cosl (x);
#elif defined(HAVE_COS)
return cos (x);
#elif defined(HAVE_COSF)
return cosf (x);
#else
#error ### no cos function available ###
#endif
}
static qse_real_t custom_awk_tan (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_TANL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return tanl (x);
#elif defined(HAVE_TAN)
return tan (x);
#elif defined(HAVE_TANF)
return tanf (x);
#else
#error ### no tan function available ###
#endif
}
static qse_real_t custom_awk_atan (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_ATANL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return atanl (x);
#elif defined(HAVE_ATAN)
return atan (x);
#elif defined(HAVE_ATANF)
return atanf (x);
#else
#error ### no atan function available ###
#endif
}
static qse_real_t custom_awk_atan2 (qse_awk_t* awk, qse_real_t x, qse_real_t y)
{
#if defined(HAVE_ATAN2L) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return atan2l (x, y);
#elif defined(HAVE_ATAN2)
return atan2 (x, y);
#elif defined(HAVE_ATAN2F)
return atan2f (x, y);
#else
#error ### no atan2 function available ###
#endif
}
static qse_real_t custom_awk_log (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_LOGL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return logl (x);
#elif defined(HAVE_LOG)
return log (x);
#elif defined(HAVE_LOGF)
return logf (x);
#else
#error ### no log function available ###
#endif
}
static qse_real_t custom_awk_exp (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_EXPL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return expl (x);
#elif defined(HAVE_EXP)
return exp (x);
#elif defined(HAVE_EXPF)
return expf (x);
#else
#error ### no exp function available ###
#endif
}
static qse_real_t custom_awk_sqrt (qse_awk_t* awk, qse_real_t x)
{
#if defined(HAVE_SQRTL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return sqrtl (x);
#elif defined(HAVE_SQRT)
return sqrt (x);
#elif defined(HAVE_SQRTF)
return sqrtf (x);
#else
#error ### no sqrt function available ###
#endif
}
static int custom_awk_sprintf (
qse_awk_t* awk, qse_char_t* buf, qse_size_t size,
const qse_char_t* fmt, ...)
@ -154,8 +258,17 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
qse_awk_prm_t prm;
xtn_t* xtn;
prm.pow = custom_awk_pow;
prm.sprintf = custom_awk_sprintf;
prm.sprintf = custom_awk_sprintf;
prm.math.pow = custom_awk_pow;
prm.math.sin = custom_awk_sin;
prm.math.cos = custom_awk_cos;
prm.math.tan = custom_awk_tan;
prm.math.atan = custom_awk_atan;
prm.math.atan2 = custom_awk_atan2;
prm.math.log = custom_awk_log;
prm.math.exp = custom_awk_exp;
prm.math.sqrt = custom_awk_sqrt;
/* create an object */
awk = qse_awk_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm);
@ -1225,251 +1338,6 @@ void* qse_awk_rtx_getxtnstd (qse_awk_rtx_t* rtx)
return (void*)((rxtn_t*)QSE_XTN(rtx) + 1);
}
/*** EXTRA BUILTIN FUNCTIONS ***/
enum
{
FNC_MATH_LD,
FNC_MATH_D,
FNC_MATH_F
};
static int fnc_math_1 (
qse_awk_rtx_t* run, const qse_cstr_t* fnm,
int type, void* f)
{
qse_size_t nargs;
qse_awk_val_t* a0;
qse_long_t lv;
qse_real_t rv;
qse_awk_val_t* r;
int n;
nargs = qse_awk_rtx_getnargs (run);
QSE_ASSERT (nargs == 1);
a0 = qse_awk_rtx_getarg (run, 0);
n = qse_awk_rtx_valtonum (run, a0, &lv, &rv);
if (n <= -1) return -1;
if (n == 0) rv = (qse_real_t)lv;
switch (type)
{
case FNC_MATH_LD:
{
long double (*rf) (long double) =
(long double(*)(long double))f;
r = qse_awk_rtx_makerealval (run, rf(rv));
break;
}
case FNC_MATH_D:
{
double (*rf) (double) = (double(*)(double))f;
r = qse_awk_rtx_makerealval (run, rf(rv));
break;
}
default:
{
float (*rf) (float);
QSE_ASSERT (type == FNC_MATH_F);
rf = (float(*)(float))f;
r = qse_awk_rtx_makerealval (run, rf(rv));
break;
}
}
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (run, r);
return 0;
}
static int fnc_math_2 (
qse_awk_rtx_t* run, const qse_cstr_t* fnm, int type, void* f)
{
qse_size_t nargs;
qse_awk_val_t* a0, * a1;
qse_long_t lv0, lv1;
qse_real_t rv0, rv1;
qse_awk_val_t* r;
int n;
nargs = qse_awk_rtx_getnargs (run);
QSE_ASSERT (nargs == 2);
a0 = qse_awk_rtx_getarg (run, 0);
a1 = qse_awk_rtx_getarg (run, 1);
n = qse_awk_rtx_valtonum (run, a0, &lv0, &rv0);
if (n <= -1) return -1;
if (n == 0) rv0 = (qse_real_t)lv0;
n = qse_awk_rtx_valtonum (run, a1, &lv1, &rv1);
if (n <= -1) return -1;
if (n == 0) rv1 = (qse_real_t)lv1;
switch (type)
{
case FNC_MATH_LD:
{
long double (*rf) (long double,long double) =
(long double(*)(long double,long double))f;
r = qse_awk_rtx_makerealval (run, rf(rv0,rv1));
break;
}
case FNC_MATH_D:
{
double (*rf) (double,double) =
(double(*)(double,double))f;
r = qse_awk_rtx_makerealval (run, rf(rv0,rv1));
break;
}
default:
{
float (*rf) (float,float);
QSE_ASSERT (type == FNC_MATH_F);
rf = (float(*)(float,float))f;
r = qse_awk_rtx_makerealval (run, rf(rv0,rv1));
break;
}
}
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (run, r);
return 0;
}
static int fnc_sin (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_SINL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)sinl
#elif defined(HAVE_SIN)
FNC_MATH_D, (void*)sin
#elif defined(HAVE_SINF)
FNC_MATH_F, (void*)sinf
#else
#error ### no sin function available ###
#endif
);
}
static int fnc_cos (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_COSL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)cosl
#elif defined(HAVE_COS)
FNC_MATH_D, (void*)cos
#elif defined(HAVE_COSF)
FNC_MATH_F, (void*)cosf
#else
#error ### no cos function available ###
#endif
);
}
static int fnc_tan (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_TANL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)tanl
#elif defined(HAVE_TAN)
FNC_MATH_D, (void*)tan
#elif defined(HAVE_TANF)
FNC_MATH_F, (void*)tanf
#else
#error ### no tan function available ###
#endif
);
}
static int fnc_atan (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_ATANL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)atanl
#elif defined(HAVE_ATAN)
FNC_MATH_D, (void*)atan
#elif defined(HAVE_ATANF)
FNC_MATH_F, (void*)atanf
#else
#error ### no atan function available ###
#endif
);
}
static int fnc_atan2 (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_2 (
run, fnm,
#if defined(HAVE_ATAN2L) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)atan2l
#elif defined(HAVE_ATAN2)
FNC_MATH_D, (void*)atan2
#elif defined(HAVE_ATAN2F)
FNC_MATH_F, (void*)atan2f
#else
#error ### no atan2 function available ###
#endif
);
}
static int fnc_log (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_LOGL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)logl
#elif defined(HAVE_LOG)
FNC_MATH_D, (void*)log
#elif defined(HAVE_LOGF)
FNC_MATH_F, (void*)logf
#else
#error ### no log function available ###
#endif
);
}
static int fnc_exp (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_EXPL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)expl
#elif defined(HAVE_EXP)
FNC_MATH_D, (void*)exp
#elif defined(HAVE_EXPF)
FNC_MATH_F, (void*)expf
#else
#error ### no exp function available ###
#endif
);
}
static int fnc_sqrt (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
return fnc_math_1 (
run, fnm,
#if defined(HAVE_SQRTL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
FNC_MATH_LD, (void*)sqrtl
#elif defined(HAVE_SQRT)
FNC_MATH_D, (void*)sqrt
#elif defined(HAVE_SQRTF)
FNC_MATH_F, (void*)sqrtf
#else
#error ### no sqrt function available ###
#endif
);
}
static int fnc_int (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
{
qse_size_t nargs;
@ -1648,14 +1516,6 @@ skip_system:
static int add_functions (qse_awk_t* awk)
{
ADDFNC (awk, QSE_T("sin"), 1, 1, fnc_sin);
ADDFNC (awk, QSE_T("cos"), 1, 1, fnc_cos);
ADDFNC (awk, QSE_T("tan"), 1, 1, fnc_tan);
ADDFNC (awk, QSE_T("atan"), 1, 1, fnc_atan);
ADDFNC (awk, QSE_T("atan2"), 2, 2, fnc_atan2);
ADDFNC (awk, QSE_T("log"), 1, 1, fnc_log);
ADDFNC (awk, QSE_T("exp"), 1, 1, fnc_exp);
ADDFNC (awk, QSE_T("sqrt"), 1, 1, fnc_sqrt);
ADDFNC (awk, QSE_T("int"), 1, 1, fnc_int);
ADDFNC (awk, QSE_T("rand"), 0, 0, fnc_rand);
ADDFNC (awk, QSE_T("srand"), 0, 1, fnc_srand);