changed qse_awk_prm_t to include basic math functions
This commit is contained in:
parent
a2a474bb34
commit
da35a4c6dc
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h 458 2011-05-13 04:06:55Z hyunghwan.chung $
|
||||
* $Id: awk.h 459 2011-05-17 14:37:51Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -355,6 +355,17 @@ struct qse_awk_nde_t
|
||||
QSE_AWK_NDE_HDR;
|
||||
};
|
||||
|
||||
typedef qse_real_t (*qse_awk_math1_t) (
|
||||
qse_awk_t* awk,
|
||||
qse_real_t x
|
||||
);
|
||||
|
||||
typedef qse_real_t (*qse_awk_math2_t) (
|
||||
qse_awk_t* awk,
|
||||
qse_real_t x,
|
||||
qse_real_t y
|
||||
);
|
||||
|
||||
typedef qse_real_t (*qse_awk_pow_t) (
|
||||
qse_awk_t* awk,
|
||||
qse_real_t x,
|
||||
@ -534,38 +545,53 @@ typedef qse_ssize_t (*qse_awk_rio_fun_t) (
|
||||
*/
|
||||
struct qse_awk_prm_t
|
||||
{
|
||||
qse_awk_pow_t pow;
|
||||
qse_awk_sprintf_t sprintf;
|
||||
|
||||
struct
|
||||
{
|
||||
qse_awk_math2_t pow;
|
||||
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 exp;
|
||||
qse_awk_math1_t sqrt;
|
||||
} math;
|
||||
|
||||
#if 0
|
||||
/* TODO: accept regular expression handling functions */
|
||||
void* (*build) (
|
||||
qse_awk_t* awk,
|
||||
const qse_char_t* ptn,
|
||||
qse_size_t len,
|
||||
int* errnum
|
||||
);
|
||||
struct
|
||||
{
|
||||
/* TODO: accept regular expression handling functions */
|
||||
void* (*build) (
|
||||
qse_awk_t* awk,
|
||||
const qse_char_t* ptn,
|
||||
qse_size_t len,
|
||||
int* errnum
|
||||
);
|
||||
|
||||
int (*match) (
|
||||
qse_awk_t* awk,
|
||||
void* code,
|
||||
int option,
|
||||
const qse_char_t* str,
|
||||
qse_size_t len,
|
||||
const qse_char_t** mptr,
|
||||
qse_size_t* mlen,
|
||||
int* errnum
|
||||
);
|
||||
int (*match) (
|
||||
qse_awk_t* awk,
|
||||
void* code,
|
||||
int option,
|
||||
const qse_char_t* str,
|
||||
qse_size_t len,
|
||||
const qse_char_t** mptr,
|
||||
qse_size_t* mlen,
|
||||
int* errnum
|
||||
);
|
||||
|
||||
void (*free) (
|
||||
qse_awk_t* awk,
|
||||
void* code
|
||||
);
|
||||
void (*free) (
|
||||
qse_awk_t* awk,
|
||||
void* code
|
||||
);
|
||||
|
||||
qse_bool_t (*isempty) (
|
||||
qse_awk_t* awk,
|
||||
void* code
|
||||
);
|
||||
qse_bool_t (*isempty) (
|
||||
qse_awk_t* awk,
|
||||
void* code
|
||||
);
|
||||
} rex;
|
||||
#endif
|
||||
};
|
||||
typedef struct qse_awk_prm_t qse_awk_prm_t;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.c 447 2011-05-01 13:28:51Z hyunghwan.chung $
|
||||
* $Id: awk.c 459 2011-05-17 14:37:51Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -72,7 +72,6 @@ static void clear_token (qse_awk_tok_t* tok)
|
||||
tok->loc.colm = 0;
|
||||
}
|
||||
|
||||
|
||||
qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
|
||||
{
|
||||
qse_awk_t* awk;
|
||||
@ -130,12 +129,28 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
|
||||
awk->mmgr = mmgr;
|
||||
|
||||
/* progagate the primitive functions */
|
||||
QSE_ASSERT (prm != QSE_NULL);
|
||||
QSE_ASSERT (prm->pow != QSE_NULL);
|
||||
QSE_ASSERT (prm->sprintf != QSE_NULL);
|
||||
if (prm == QSE_NULL ||
|
||||
prm->pow == QSE_NULL ||
|
||||
prm->sprintf == QSE_NULL)
|
||||
QSE_ASSERT (prm != QSE_NULL);
|
||||
QSE_ASSERT (prm->sprintf != 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.exp != QSE_NULL);
|
||||
QSE_ASSERT (prm->math.sqrt != QSE_NULL);
|
||||
if (prm == QSE_NULL ||
|
||||
prm->sprintf == 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.exp == QSE_NULL ||
|
||||
prm->math.sqrt == QSE_NULL)
|
||||
{
|
||||
QSE_AWK_FREE (awk, awk);
|
||||
return QSE_NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fnc.c 441 2011-04-22 14:28:43Z hyunghwan.chung $
|
||||
* $Id: fnc.c 459 2011-05-17 14:37:51Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -20,18 +20,27 @@
|
||||
|
||||
#include "awk.h"
|
||||
|
||||
static int fnc_close (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_fflush (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_index (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_length (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_substr (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_split (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_tolower (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_toupper (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_gsub (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_sub (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_match (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_sprintf (qse_awk_rtx_t*, const qse_cstr_t*);
|
||||
static int fnc_close (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_fflush (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_index (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_length (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_substr (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_split (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_tolower (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_toupper (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_gsub (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_sub (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_match (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_sprintf (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
|
||||
static int fnc_sin (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_cos (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_tan (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_atan (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_atan2 (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_log (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_exp (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
static int fnc_sqrt (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm);
|
||||
|
||||
#undef MAX
|
||||
#define MAX QSE_TYPE_UNSIGNED_MAX(qse_size_t)
|
||||
@ -67,6 +76,16 @@ static qse_awk_fnc_t sys_fnc[] =
|
||||
{ {QSE_T("match"), 5}, 0, 0, {2, 3, QSE_T("vxv")}, fnc_match},
|
||||
{ {QSE_T("sprintf"), 7}, 0, 0, {1, MAX, QSE_NULL}, fnc_sprintf},
|
||||
|
||||
/* math functions */
|
||||
{ {QSE_T("sin"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_sin},
|
||||
{ {QSE_T("cos"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_cos},
|
||||
{ {QSE_T("tan"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_tan},
|
||||
{ {QSE_T("atan"), 4}, 0, 0, {1, 1, QSE_NULL}, fnc_atan},
|
||||
{ {QSE_T("atan2"), 5}, 0, 0, {2, 2, QSE_NULL}, fnc_atan2},
|
||||
{ {QSE_T("log"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_log},
|
||||
{ {QSE_T("exp"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_exp},
|
||||
{ {QSE_T("sqrt"), 4}, 0, 0, {1, 1, QSE_NULL}, fnc_sqrt},
|
||||
|
||||
{ {QSE_NULL, 0}, 0, 0, {0, 0, QSE_NULL}, QSE_NULL}
|
||||
};
|
||||
|
||||
@ -169,6 +188,7 @@ qse_awk_fnc_t* qse_awk_getfnc (
|
||||
qse_size_t l;
|
||||
|
||||
/* search the system function table */
|
||||
/* TODO: some speed up? binary search by ordering the table? */
|
||||
for (fnc = sys_fnc; fnc->name.ptr != QSE_NULL; fnc++)
|
||||
{
|
||||
if (fnc->valid != 0 &&
|
||||
@ -1527,3 +1547,93 @@ static int fnc_sprintf (qse_awk_rtx_t* run, const qse_cstr_t* fnm)
|
||||
qse_awk_rtx_setretval (run, a0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_math_1 (
|
||||
qse_awk_rtx_t* rtx, const qse_cstr_t* fnm, qse_awk_math1_t 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 (rtx);
|
||||
QSE_ASSERT (nargs == 1);
|
||||
|
||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||
|
||||
n = qse_awk_rtx_valtonum (rtx, a0, &lv, &rv);
|
||||
if (n <= -1) return -1;
|
||||
if (n == 0) rv = (qse_real_t)lv;
|
||||
|
||||
r = qse_awk_rtx_makerealval (rtx, f (rtx->awk, 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_cstr_t* fnm, qse_awk_math2_t 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 (rtx);
|
||||
QSE_ASSERT (nargs == 2);
|
||||
|
||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||
a1 = qse_awk_rtx_getarg (rtx, 1);
|
||||
|
||||
n = qse_awk_rtx_valtonum (rtx, a0, &lv0, &rv0);
|
||||
if (n <= -1) return -1;
|
||||
if (n == 0) rv0 = (qse_real_t)lv0;
|
||||
|
||||
n = qse_awk_rtx_valtonum (rtx, a1, &lv1, &rv1);
|
||||
if (n <= -1) return -1;
|
||||
if (n == 0) rv1 = (qse_real_t)lv1;
|
||||
|
||||
r = qse_awk_rtx_makerealval (rtx, f (rtx->awk, rv0, rv1));
|
||||
if (r == QSE_NULL) return -1;
|
||||
|
||||
qse_awk_rtx_setretval (rtx, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fnc_sin (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.sin);
|
||||
}
|
||||
static int fnc_cos (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.cos);
|
||||
}
|
||||
static int fnc_tan (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.tan);
|
||||
}
|
||||
static int fnc_atan (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.atan);
|
||||
}
|
||||
static int fnc_atan2 (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_2 (rtx, fnm, rtx->awk->prm.math.atan2);
|
||||
}
|
||||
static int fnc_log (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.log);
|
||||
}
|
||||
static int fnc_exp (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.exp);
|
||||
}
|
||||
static int fnc_sqrt (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm)
|
||||
{
|
||||
return fnc_math_1 (rtx, fnm, rtx->awk->prm.math.sqrt);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c 441 2011-04-22 14:28:43Z hyunghwan.chung $
|
||||
* $Id: run.c 459 2011-05-17 14:37:51Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2011 Chung, Hyung-Hwan.
|
||||
This file is part of QSE.
|
||||
@ -702,7 +702,7 @@ qse_awk_rtx_t* qse_awk_rtx_open (
|
||||
{
|
||||
qse_awk_rtx_t* rtx;
|
||||
|
||||
QSE_ASSERTX (awk->prm.pow != QSE_NULL, "Call qse_awk_setprm() first");
|
||||
QSE_ASSERTX (awk->prm.math.pow != QSE_NULL, "Call qse_awk_setprm() first");
|
||||
QSE_ASSERTX (awk->prm.sprintf != QSE_NULL, "Call qse_awk_setprm() first");
|
||||
|
||||
/* clear the awk error code */
|
||||
@ -4632,7 +4632,7 @@ static qse_awk_val_t* eval_binop_exp (
|
||||
qse_real_t r1, r2;
|
||||
qse_awk_val_t* res;
|
||||
|
||||
QSE_ASSERTX (rtx->awk->prm.pow != QSE_NULL,
|
||||
QSE_ASSERTX (rtx->awk->prm.math.pow != QSE_NULL,
|
||||
"the pow function should be provided when the awk object"
|
||||
" is created to make the exponentiation work properly.");
|
||||
|
||||
@ -4695,7 +4695,7 @@ static qse_awk_val_t* eval_binop_exp (
|
||||
/* left - int, right - real */
|
||||
res = qse_awk_rtx_makerealval (
|
||||
rtx,
|
||||
rtx->awk->prm.pow (
|
||||
rtx->awk->prm.math.pow (
|
||||
rtx->awk, (qse_real_t)l1, (qse_real_t)r2
|
||||
)
|
||||
);
|
||||
@ -4706,7 +4706,7 @@ static qse_awk_val_t* eval_binop_exp (
|
||||
QSE_ASSERT (n3 == 3);
|
||||
res = qse_awk_rtx_makerealval (
|
||||
rtx,
|
||||
rtx->awk->prm.pow (
|
||||
rtx->awk->prm.math.pow (
|
||||
rtx->awk, (qse_real_t)r1,(qse_real_t)r2
|
||||
)
|
||||
);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user