removed most math functions from the main engine. migrated them to the math module

This commit is contained in:
hyung-hwan 2014-07-01 15:27:27 +00:00
parent 0c5d9eee9c
commit 7423092c39
11 changed files with 341 additions and 582 deletions

View File

@ -1288,15 +1288,6 @@ protected:
// primitive handlers
virtual flt_t pow (flt_t x, flt_t y) = 0;
virtual flt_t mod (flt_t x, flt_t y) = 0;
virtual flt_t sin (flt_t x) = 0;
virtual flt_t cos (flt_t x) = 0;
virtual flt_t tan (flt_t x) = 0;
virtual flt_t atan (flt_t x) = 0;
virtual flt_t atan2 (flt_t x, flt_t y) = 0;
virtual flt_t log (flt_t x) = 0;
virtual flt_t log10 (flt_t x) = 0;
virtual flt_t exp (flt_t x) = 0;
virtual flt_t sqrt (flt_t x) = 0;
virtual void* modopen (const mod_spec_t* spec) = 0;
virtual void modclose (void* handle) = 0;
@ -1325,15 +1316,6 @@ protected:
static flt_t pow (awk_t* awk, flt_t x, flt_t y);
static flt_t mod (awk_t* awk, flt_t x, flt_t y);
static flt_t sin (awk_t* awk, flt_t x);
static flt_t cos (awk_t* awk, flt_t x);
static flt_t tan (awk_t* awk, flt_t x);
static flt_t atan (awk_t* awk, flt_t x);
static flt_t atan2 (awk_t* awk, flt_t x, flt_t y);
static flt_t log (awk_t* awk, flt_t x);
static flt_t log10 (awk_t* awk, flt_t x);
static flt_t exp (awk_t* awk, flt_t x);
static flt_t sqrt (awk_t* awk, flt_t x);
static void* modopen (awk_t* awk, const mod_spec_t* spec);
static void modclose (awk_t* awk, void* handle);

View File

@ -158,15 +158,6 @@ protected:
flt_t pow (flt_t x, flt_t y);
flt_t mod (flt_t x, flt_t y);
flt_t sin (flt_t x);
flt_t cos (flt_t x);
flt_t tan (flt_t x);
flt_t atan (flt_t x);
flt_t atan2 (flt_t x, flt_t y);
flt_t log (flt_t x);
flt_t log10 (flt_t x);
flt_t exp (flt_t x);
flt_t sqrt (flt_t x);
void* modopen (const mod_spec_t* spec);
void modclose (void* handle);

View File

@ -669,15 +669,6 @@ struct qse_awk_prm_t
{
qse_awk_math2_t pow; /**< floating-point power function */
qse_awk_math2_t mod; /**< floating-point remainder function */
qse_awk_math1_t sin;
qse_awk_math1_t cos;
qse_awk_math1_t tan;
qse_awk_math1_t atan;
qse_awk_math2_t atan2;
qse_awk_math1_t log;
qse_awk_math1_t log10;
qse_awk_math1_t exp;
qse_awk_math1_t sqrt;
} math;
qse_awk_modopen_t modopen;
@ -786,6 +777,16 @@ struct qse_awk_fnc_spec_t
qse_size_t min; /**< min. numbers of argument for a function */
qse_size_t max; /**< max. numbers of argument for a function */
const qse_char_t* spec;
/**< argument specifier
* if min is greater than max, spec points to an external module
* name where the function is found. otherwise, spec can be QSE_NULL
* to indicate all arguments are passed by value or point to a
* argument specification string composed of 'max' characters.
* Each character can be one of:
* - v: value
* - r: reference
* - x:regular expression
*/
} arg;
/** pointer to the function implementing this function */

View File

@ -1118,15 +1118,6 @@ int Awk::open ()
QSE_MEMSET (&prm, 0, QSE_SIZEOF(prm));
prm.math.pow = pow;
prm.math.mod = mod;
prm.math.sin = sin;
prm.math.cos = cos;
prm.math.tan = tan;
prm.math.atan = atan;
prm.math.atan2 = atan2;
prm.math.log = log;
prm.math.log10 = log10;
prm.math.exp = exp;
prm.math.sqrt = sqrt;
prm.modopen = modopen;
prm.modclose = modclose;
prm.modsym = modsym;
@ -2011,60 +2002,6 @@ Awk::flt_t Awk::mod (awk_t* awk, flt_t x, flt_t y)
return xtn->awk->mod (x, y);
}
Awk::flt_t Awk::sin (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->sin (x);
}
Awk::flt_t Awk::cos (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->cos (x);
}
Awk::flt_t Awk::tan (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->tan (x);
}
Awk::flt_t Awk::atan (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->atan (x);
}
Awk::flt_t Awk::atan2 (awk_t* awk, flt_t x, flt_t y)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->atan2 (x, y);
}
Awk::flt_t Awk::log (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->log (x);
}
Awk::flt_t Awk::log10 (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->log10 (x);
}
Awk::flt_t Awk::exp (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->exp (x);
}
Awk::flt_t Awk::sqrt (awk_t* awk, flt_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->sqrt (x);
}
void* Awk::modopen (awk_t* awk, const mod_spec_t* spec)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);

View File

@ -64,15 +64,6 @@ extern "C" { // some gcc distros don't have extern "C" declared in the header fi
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define HAVE_POW
# define HAVE_FMOD
# define HAVE_SIN
# define HAVE_COS
# define HAVE_TAN
# define HAVE_ATAN
# define HAVE_ATAN2
# define HAVE_LOG
# define HAVE_LOG10
# define HAVE_EXP
# define HAVE_SQRT
# endif
#endif
@ -1206,143 +1197,6 @@ StdAwk::flt_t StdAwk::mod (flt_t x, flt_t y)
#endif
}
StdAwk::flt_t StdAwk::sin (flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_SINQ)
return ::sinq (x);
#elif 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
}
StdAwk::flt_t StdAwk::cos (flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_COSQ)
return ::cosq (x);
#elif 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
}
StdAwk::flt_t StdAwk::tan (flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_TANQ)
return ::tanq (x);
#elif 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
}
StdAwk::flt_t StdAwk::atan (flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_ATANQ)
return ::atanq (x);
#elif 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
}
StdAwk::flt_t StdAwk::atan2 (flt_t x, flt_t y)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_ATAN2Q)
return ::atan2q (x, y);
#elif 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
}
StdAwk::flt_t StdAwk::log (flt_t x)
{
/* natural logarithm */
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_LOGQ)
return ::logq (x);
#elif 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
}
StdAwk::flt_t StdAwk::log10 (flt_t x)
{
/* common logarithm */
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_LOG10Q)
return ::log10q (x);
#elif defined(HAVE_LOG10L) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return ::log10l (x);
#elif defined(HAVE_LOG10)
return ::log10 (x);
#elif defined(HAVE_LOG10F)
return ::log10f (x);
#else
#error ### no log10 function available ###
#endif
}
StdAwk::flt_t StdAwk::exp (flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_EXPQ)
return ::expq (x);
#elif 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
}
StdAwk::flt_t StdAwk::sqrt (flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_SQRTQ)
return ::sqrtq (x);
#elif 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
}
void* StdAwk::modopen (const mod_spec_t* spec)
{
#if defined(QSE_ENABLE_STATIC_MODULE)

View File

@ -119,26 +119,10 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* pr
/* progagate the primitive functions */
QSE_ASSERT (prm != QSE_NULL);
QSE_ASSERT (prm->math.pow != QSE_NULL);
QSE_ASSERT (prm->math.sin != QSE_NULL);
QSE_ASSERT (prm->math.cos != QSE_NULL);
QSE_ASSERT (prm->math.tan != QSE_NULL);
QSE_ASSERT (prm->math.atan != QSE_NULL);
QSE_ASSERT (prm->math.atan2 != QSE_NULL);
QSE_ASSERT (prm->math.log != QSE_NULL);
QSE_ASSERT (prm->math.log10 != QSE_NULL);
QSE_ASSERT (prm->math.exp != QSE_NULL);
QSE_ASSERT (prm->math.sqrt != QSE_NULL);
if (prm == QSE_NULL ||
prm->math.pow == QSE_NULL ||
prm->math.sin == QSE_NULL ||
prm->math.cos == QSE_NULL ||
prm->math.tan == QSE_NULL ||
prm->math.atan == QSE_NULL ||
prm->math.atan2 == QSE_NULL ||
prm->math.log == QSE_NULL ||
prm->math.log10 == QSE_NULL ||
prm->math.exp == QSE_NULL ||
prm->math.sqrt == QSE_NULL)
QSE_ASSERT (prm->math.mod != QSE_NULL);
if (prm == QSE_NULL ||
prm->math.pow == QSE_NULL ||
prm->math.mod == QSE_NULL)
{
QSE_AWK_FREE (awk, awk);
return QSE_NULL;

View File

@ -38,6 +38,9 @@ static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
* If the first character of the specifer is 'R', all
* parameters are passed by reference regarless of the remaining
* chracters.
*
* NOTE: If min is greater than max, the specifier indicate the
* name of the module where the function is located.
*/
static qse_awk_fnc_t sysfnctab[] =
{
@ -61,15 +64,15 @@ static qse_awk_fnc_t sysfnctab[] =
{ {QSE_T("sprintf"), 7}, 0, { {1, A_MAX, QSE_NULL}, qse_awk_fnc_sprintf, 0 }, QSE_NULL},
/* math functions */
{ {QSE_T("sin"), 3}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_sin, 0 }, QSE_NULL},
{ {QSE_T("cos"), 3}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_cos, 0 }, QSE_NULL},
{ {QSE_T("tan"), 3}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_tan, 0 }, QSE_NULL},
{ {QSE_T("atan"), 4}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_atan, 0 }, QSE_NULL},
{ {QSE_T("atan2"), 5}, 0, { {2, 2, QSE_NULL}, qse_awk_fnc_atan2, 0 }, QSE_NULL},
{ {QSE_T("log"), 3}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_log, 0 }, QSE_NULL},
{ {QSE_T("log10"), 5}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_log10, 0 }, QSE_NULL},
{ {QSE_T("exp"), 3}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_exp, 0 }, QSE_NULL},
{ {QSE_T("sqrt"), 4}, 0, { {1, 1, QSE_NULL}, qse_awk_fnc_sqrt, 0 }, QSE_NULL}
{ {QSE_T("sin"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("cos"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("tan"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("atan"), 4}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("atan2"), 5}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("log"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("log10"), 5}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("exp"), 3}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL},
{ {QSE_T("sqrt"), 4}, 0, { {A_MAX, 0, QSE_T("math") }, QSE_NULL, 0 }, QSE_NULL}
};
qse_awk_fnc_t* qse_awk_addfnc (qse_awk_t* awk, const qse_char_t* name, const qse_awk_fnc_spec_t* spec)
@ -1269,103 +1272,6 @@ oops:
return -1;
}
int qse_awk_fnc_math_1 (
qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math1_t f)
{
qse_size_t nargs;
qse_awk_val_t* a0;
qse_awk_flt_t rv;
qse_awk_val_t* r;
int n;
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 1);
a0 = qse_awk_rtx_getarg (rtx, 0);
n = qse_awk_rtx_valtoflt (rtx, a0, &rv);
if (n <= -1) return -1;
r = qse_awk_rtx_makefltval (rtx, f (rtx->awk, rv));
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, r);
return 0;
}
int qse_awk_fnc_math_2 (
qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math2_t f)
{
qse_size_t nargs;
qse_awk_val_t* a0, * a1;
qse_awk_flt_t rv0, rv1;
qse_awk_val_t* r;
int n;
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 2);
a0 = qse_awk_rtx_getarg (rtx, 0);
a1 = qse_awk_rtx_getarg (rtx, 1);
n = qse_awk_rtx_valtoflt (rtx, a0, &rv0);
if (n <= -1) return -1;
n = qse_awk_rtx_valtoflt (rtx, a1, &rv1);
if (n <= -1) return -1;
r = qse_awk_rtx_makefltval (rtx, f (rtx->awk, rv0, rv1));
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, r);
return 0;
}
int qse_awk_fnc_sin (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.sin);
}
int qse_awk_fnc_cos (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.cos);
}
int qse_awk_fnc_tan (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.tan);
}
int qse_awk_fnc_atan (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.atan);
}
int qse_awk_fnc_atan2 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_2 (rtx, fi, rtx->awk->prm.math.atan2);
}
int qse_awk_fnc_log (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.log);
}
int qse_awk_fnc_log10 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.log10);
}
int qse_awk_fnc_exp (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.exp);
}
int qse_awk_fnc_sqrt (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, rtx->awk->prm.math.sqrt);
}
static int fnc_int (qse_awk_rtx_t* run, const qse_awk_fnc_info_t* fi)
{
qse_size_t nargs;

View File

@ -33,7 +33,9 @@ struct qse_awk_fnc_t
* this ia mainly for the weird length() function */
qse_awk_fnc_spec_t spec;
qse_awk_mod_t* mod; /* if it's associated to a module */
const qse_char_t* owner; /* set this to a module name if a built-in function is located in a module */
qse_awk_mod_t* mod; /* set by the engine to a valid pointer if it's associated to a module */
};
#ifdef __cplusplus
@ -54,21 +56,6 @@ int qse_awk_fnc_tolower (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_toupper (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_sprintf (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_sin (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_cos (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_tan (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_atan (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_atan2 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_log (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_log10 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_exp (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_sqrt (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
int qse_awk_fnc_math_1 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math1_t f);
int qse_awk_fnc_math_2 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math2_t f);
#ifdef __cplusplus
}
#endif

View File

@ -40,9 +40,72 @@
# define HAVE_TANH
# define HAVE_ASIN
# define HAVE_ACOS
# define HAVE_SIN
# define HAVE_COS
# define HAVE_TAN
# define HAVE_ATAN
# define HAVE_ATAN2
# define HAVE_LOG
# define HAVE_LOG10
# define HAVE_EXP
# define HAVE_SQRT
# endif
#endif
static int fnc_math_1 (
qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math1_t f)
{
qse_size_t nargs;
qse_awk_val_t* a0;
qse_awk_flt_t rv;
qse_awk_val_t* r;
int n;
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 1);
a0 = qse_awk_rtx_getarg (rtx, 0);
n = qse_awk_rtx_valtoflt (rtx, a0, &rv);
if (n <= -1) return -1;
r = qse_awk_rtx_makefltval (rtx, f (qse_awk_rtx_getawk(rtx), rv));
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, r);
return 0;
}
static int fnc_math_2 (
qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi, qse_awk_math2_t f)
{
qse_size_t nargs;
qse_awk_val_t* a0, * a1;
qse_awk_flt_t rv0, rv1;
qse_awk_val_t* r;
int n;
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 2);
a0 = qse_awk_rtx_getarg (rtx, 0);
a1 = qse_awk_rtx_getarg (rtx, 1);
n = qse_awk_rtx_valtoflt (rtx, a0, &rv0);
if (n <= -1) return -1;
n = qse_awk_rtx_valtoflt (rtx, a1, &rv1);
if (n <= -1) return -1;
r = qse_awk_rtx_makefltval (rtx, f (qse_awk_rtx_getawk(rtx), rv0, rv1));
if (r == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, r);
return 0;
}
static qse_awk_flt_t math_ceil (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_CEILQ)
@ -163,48 +226,236 @@ static qse_awk_flt_t math_acos (qse_awk_t* awk, qse_awk_flt_t x)
#endif
}
/* ----------------------------------------------------------------------- */
static qse_awk_flt_t math_sin (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_SINQ)
return sinq (x);
#elif 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_awk_flt_t math_cos (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_COSQ)
return cosq (x);
#elif 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_awk_flt_t math_tan (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_TANQ)
return tanq (x);
#elif 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_awk_flt_t math_atan (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_ATANQ)
return atanq (x);
#elif 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_awk_flt_t math_atan2 (qse_awk_t* awk, qse_awk_flt_t x, qse_awk_flt_t y)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_ATAN2Q)
return atan2q (x, y);
#elif 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_awk_flt_t math_log (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_LOGQ)
return logq (x);
#elif 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_awk_flt_t math_log10 (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_LOG10Q)
return log10q (x);
#elif defined(HAVE_LOG10L) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return log10l (x);
#elif defined(HAVE_LOG10)
return log10 (x);
#elif defined(HAVE_LOG10F)
return log10f (x);
#else
#error ### no log10 function available ###
#endif
}
static qse_awk_flt_t math_exp (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_EXPQ)
return expq (x);
#elif 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_awk_flt_t math_sqrt (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_SQRTQ)
return sqrtq (x);
#elif 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 fnc_ceil (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_ceil);
return fnc_math_1 (rtx, fi, math_ceil);
}
static int fnc_floor (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_floor);
return fnc_math_1 (rtx, fi, math_floor);
}
static int fnc_round (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_round);
return fnc_math_1 (rtx, fi, math_round);
}
static int fnc_sinh (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_sinh);
return fnc_math_1 (rtx, fi, math_sinh);
}
static int fnc_cosh (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_cosh);
return fnc_math_1 (rtx, fi, math_cosh);
}
static int fnc_tanh (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_tanh);
return fnc_math_1 (rtx, fi, math_tanh);
}
static int fnc_asin (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_asin);
return fnc_math_1 (rtx, fi, math_asin);
}
static int fnc_acos (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return qse_awk_fnc_math_1 (rtx, fi, math_acos);
return fnc_math_1 (rtx, fi, math_acos);
}
/* ---------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
static int fnc_sin (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_sin);
}
static int fnc_cos (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_cos);
}
static int fnc_tan (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_tan);
}
static int fnc_atan (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_atan);
}
static int fnc_atan2 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_2 (rtx, fi, math_atan2);
}
static int fnc_log (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_log);
}
static int fnc_log10 (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_log10);
}
static int fnc_exp (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_exp);
}
static int fnc_sqrt (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
return fnc_math_1 (rtx, fi, math_sqrt);
}
/* ----------------------------------------------------------------------- */
typedef struct fnctab_t fnctab_t;
struct fnctab_t
@ -216,23 +467,23 @@ struct fnctab_t
static fnctab_t fnctab[] =
{
/* keep this table sorted for binary search in query(). */
{ QSE_T("acos"), { { 1, 1, QSE_NULL }, fnc_acos, 0 } },
{ QSE_T("asin"), { { 1, 1, QSE_NULL }, fnc_asin, 0 } },
{ QSE_T("atan"), { { 1, 1, QSE_NULL }, qse_awk_fnc_atan, 0 } },
{ QSE_T("atan2"), { { 2, 2, QSE_NULL }, qse_awk_fnc_atan2, 0 } },
{ QSE_T("ceil"), { { 1, 1, QSE_NULL }, fnc_ceil, 0 } },
{ QSE_T("cos"), { { 1, 1, QSE_NULL }, qse_awk_fnc_cos, 0 } },
{ QSE_T("cosh"), { { 1, 1, QSE_NULL }, fnc_cosh, 0 } },
{ QSE_T("exp"), { { 1, 1, QSE_NULL }, qse_awk_fnc_exp, 0 } },
{ QSE_T("floor"), { { 1, 1, QSE_NULL }, fnc_floor, 0 } },
{ QSE_T("log"), { { 1, 1, QSE_NULL }, qse_awk_fnc_log, 0 } },
{ QSE_T("log10"), { { 1, 1, QSE_NULL }, qse_awk_fnc_log10, 0 } },
{ QSE_T("round"), { { 1, 1, QSE_NULL }, fnc_round, 0 } },
{ QSE_T("sin"), { { 1, 1, QSE_NULL }, qse_awk_fnc_sin, 0 } },
{ QSE_T("sinh"), { { 1, 1, QSE_NULL }, fnc_sinh, 0 } },
{ QSE_T("sqrt"), { { 1, 1, QSE_NULL }, qse_awk_fnc_sqrt, 0 } },
{ QSE_T("tan"), { { 1, 1, QSE_NULL }, qse_awk_fnc_tan, 0 } },
{ QSE_T("tanh"), { { 1, 1, QSE_NULL }, fnc_tanh, 0 } }
{ QSE_T("acos"), { { 1, 1, QSE_NULL }, fnc_acos, 0 } },
{ QSE_T("asin"), { { 1, 1, QSE_NULL }, fnc_asin, 0 } },
{ QSE_T("atan"), { { 1, 1, QSE_NULL }, fnc_atan, 0 } },
{ QSE_T("atan2"), { { 2, 2, QSE_NULL }, fnc_atan2, 0 } },
{ QSE_T("ceil"), { { 1, 1, QSE_NULL }, fnc_ceil, 0 } },
{ QSE_T("cos"), { { 1, 1, QSE_NULL }, fnc_cos, 0 } },
{ QSE_T("cosh"), { { 1, 1, QSE_NULL }, fnc_cosh, 0 } },
{ QSE_T("exp"), { { 1, 1, QSE_NULL }, fnc_exp, 0 } },
{ QSE_T("floor"), { { 1, 1, QSE_NULL }, fnc_floor, 0 } },
{ QSE_T("log"), { { 1, 1, QSE_NULL }, fnc_log, 0 } },
{ QSE_T("log10"), { { 1, 1, QSE_NULL }, fnc_log10, 0 } },
{ QSE_T("round"), { { 1, 1, QSE_NULL }, fnc_round, 0 } },
{ QSE_T("sin"), { { 1, 1, QSE_NULL }, fnc_sin, 0 } },
{ QSE_T("sinh"), { { 1, 1, QSE_NULL }, fnc_sinh, 0 } },
{ QSE_T("sqrt"), { { 1, 1, QSE_NULL }, fnc_sqrt, 0 } },
{ QSE_T("tan"), { { 1, 1, QSE_NULL }, fnc_tan, 0 } },
{ QSE_T("tanh"), { { 1, 1, QSE_NULL }, fnc_tanh, 0 } }
};
static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym)

View File

@ -242,6 +242,10 @@ static qse_awk_nde_t* parse_fncall (
qse_awk_t* awk, const qse_xstr_t* name,
qse_awk_fnc_t* fnc, const qse_awk_loc_t* xloc, int noarg);
static qse_awk_nde_t* parse_primary_ident_segs (
qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_xstr_t* full,
const qse_xstr_t segs[], int nsegs);
static int get_token (qse_awk_t* awk);
static int preget_token (qse_awk_t* awk);
static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok);
@ -3090,6 +3094,7 @@ static qse_awk_nde_t* parse_expr_basic (
nde = parse_logical_or (awk, xloc);
if (nde == QSE_NULL) return QSE_NULL;
if (MATCH(awk,TOK_QUEST))
if (MATCH(awk,TOK_QUEST))
{
qse_awk_loc_t eloc;
@ -4859,24 +4864,36 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
fnc = qse_awk_findfnc (awk, (const qse_cstr_t*)name);
if (fnc)
{
if (MATCH(awk,TOK_LPAREN))
if (MATCH(awk,TOK_LPAREN) || fnc->dfl0)
{
nde = parse_fncall (awk, name, fnc, xloc, 0);
if (fnc->spec.arg.min > fnc->spec.arg.max)
{
/* this intrinsic function is located in the specificed module.
* convert the function call to a module call. i do this to
* exclude some instrinsic functions from the main engine.
* e.g) sin -> math::sin
* cos -> math::cos
*/
qse_xstr_t segs[2];
QSE_ASSERT (fnc->spec.arg.spec != QSE_NULL);
segs[0].ptr = (qse_char_t*)fnc->spec.arg.spec;
segs[0].len = qse_strlen(fnc->spec.arg.spec);
segs[1] = *name;
return parse_primary_ident_segs (awk, xloc, name, segs, 2);
}
/* fnc->dfl0 means that the function can be called without ().
* i.e. length */
nde = parse_fncall (awk, name, fnc, xloc, (fnc->dfl0? 1: 0));
}
else
{
if (fnc->dfl0)
{
/* handles a function that assumes ()
* when () is missing. i.e. length */
nde = parse_fncall (awk, name, fnc, xloc, 1);
}
else
{
/* an intrinsic function should be in the form
* of the function call */
SETERR_TOK (awk, QSE_AWK_ELPAREN);
}
/* an intrinsic function should be in the form
* of the function call */
SETERR_TOK (awk, QSE_AWK_ELPAREN);
}
}
/* now we know that name is a normal identifier. */
@ -5016,6 +5033,8 @@ static qse_awk_nde_t* parse_primary_ident_segs (
qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_xstr_t* full,
const qse_xstr_t segs[], int nsegs)
{
/* parse xxx::yyy */
qse_awk_nde_t* nde = QSE_NULL;
qse_awk_mod_t* mod;
qse_awk_mod_sym_t sym;
@ -5251,12 +5270,12 @@ static qse_awk_nde_t* parse_hashidx (
switch (fnname)
{
case FNTYPE_FNC:
SETERR_ARG_LOC (
SETERR_ARG_LOC (
awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
goto exit_func;
case FNTYPE_FUN:
SETERR_ARG_LOC (
SETERR_ARG_LOC (
awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
goto exit_func;
}

View File

@ -63,15 +63,6 @@
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define HAVE_POW
# define HAVE_FMOD
# define HAVE_SIN
# define HAVE_COS
# define HAVE_TAN
# define HAVE_ATAN
# define HAVE_ATAN2
# define HAVE_LOG
# define HAVE_LOG10
# define HAVE_EXP
# define HAVE_SQRT
# endif
#endif
@ -188,141 +179,6 @@ static qse_awk_flt_t custom_awk_mod (qse_awk_t* awk, qse_awk_flt_t x, qse_awk_fl
#endif
}
static qse_awk_flt_t custom_awk_sin (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_SINQ)
return sinq (x);
#elif 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_awk_flt_t custom_awk_cos (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_COSQ)
return cosq (x);
#elif 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_awk_flt_t custom_awk_tan (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_TANQ)
return tanq (x);
#elif 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_awk_flt_t custom_awk_atan (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_ATANQ)
return atanq (x);
#elif 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_awk_flt_t custom_awk_atan2 (qse_awk_t* awk, qse_awk_flt_t x, qse_awk_flt_t y)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_ATAN2Q)
return atan2q (x, y);
#elif 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_awk_flt_t custom_awk_log (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_LOGQ)
return logq (x);
#elif 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_awk_flt_t custom_awk_log10 (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_LOG10Q)
return log10q (x);
#elif defined(HAVE_LOG10L) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return log10l (x);
#elif defined(HAVE_LOG10)
return log10 (x);
#elif defined(HAVE_LOG10F)
return log10f (x);
#else
#error ### no log10 function available ###
#endif
}
static qse_awk_flt_t custom_awk_exp (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_EXPQ)
return expq (x);
#elif 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_awk_flt_t custom_awk_sqrt (qse_awk_t* awk, qse_awk_flt_t x)
{
#if defined(QSE_USE_AWK_FLTMAX) && defined(HAVE_SQRTQ)
return sqrtq (x);
#elif 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 void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec)
{
#if defined(QSE_ENABLE_STATIC_MODULE)
@ -553,15 +409,6 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
prm.math.pow = custom_awk_pow;
prm.math.mod = custom_awk_mod;
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.log10 = custom_awk_log10;
prm.math.exp = custom_awk_exp;
prm.math.sqrt = custom_awk_sqrt;
prm.modopen = custom_awk_modopen;
prm.modclose = custom_awk_modclose;