changed qse_awk_prm_t to include basic math functions
This commit is contained in:
		| @ -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); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user