added floating-pointer remainder handler for qse_awk_t

This commit is contained in:
hyung-hwan 2011-07-24 03:03:48 +00:00
parent 4b531aa248
commit 59afc79821
12 changed files with 256 additions and 119 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.c 510 2011-07-20 16:17:16Z hyunghwan.chung $
* $Id: awk.c 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -390,7 +390,7 @@ struct opttab_t
{
{ QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") },
{ QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") },
{ QSE_T("extraops"), QSE_AWK_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,//)") },
{ QSE_T("extraops"), QSE_AWK_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,\\)") },
{ QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") },
{ QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") },
{ QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") },

6
qse/configure vendored
View File

@ -15444,7 +15444,7 @@ done
OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS"
for ac_func in powl sinl cosl tanl atanl atan2l logl expl sqrtl
for ac_func in powl fmodl sinl cosl tanl atanl atan2l logl expl sqrtl
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -15456,7 +15456,7 @@ _ACEOF
fi
done
for ac_func in pow sin cos tan atan atan2 log exp sqrt
for ac_func in pow fmod sin cos tan atan atan2 log exp sqrt
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -15468,7 +15468,7 @@ _ACEOF
fi
done
for ac_func in powf sinf cosf tanf atanf atan2f logf expf sqrtf
for ac_func in powf fmodf sinf cosf tanf atanf atan2f logf expf sqrtf
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -102,9 +102,9 @@ AC_CHECK_FUNCS([backtrace backtrace_symbols])
OLDLIBS="$LIBS"
LIBS="$LIBM $LIBS"
AC_CHECK_FUNCS([powl sinl cosl tanl atanl atan2l logl expl sqrtl])
AC_CHECK_FUNCS([pow sin cos tan atan atan2 log exp sqrt])
AC_CHECK_FUNCS([powf sinf cosf tanf atanf atan2f logf expf sqrtf])
AC_CHECK_FUNCS([powl fmodl sinl cosl tanl atanl atan2l logl expl sqrtl])
AC_CHECK_FUNCS([pow fmod sin cos tan atan atan2 log exp sqrt])
AC_CHECK_FUNCS([powf fmodf sinf cosf tanf atanf atan2f logf expf sqrtf])
LIBS="$OLDLIBS"
dnl check the size of primitive data types

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.hpp 479 2011-05-24 15:14:58Z hyunghwan.chung $
* $Id: Awk.hpp 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -1092,6 +1092,7 @@ protected:
const char_t* fmt, va_list arg) = 0;
virtual real_t pow (real_t x, real_t y) = 0;
virtual real_t mod (real_t x, real_t y) = 0;
virtual real_t sin (real_t x) = 0;
virtual real_t cos (real_t x) = 0;
virtual real_t tan (real_t x) = 0;
@ -1124,6 +1125,7 @@ protected:
static int sprintf (awk_t* data, char_t* buf, size_t size,
const char_t* fmt, ...);
static real_t pow (awk_t* data, real_t x, real_t y);
static real_t mod (awk_t* data, real_t x, real_t y);
static real_t sin (awk_t* data, real_t x);
static real_t cos (awk_t* data, real_t x);
static real_t tan (awk_t* data, real_t x);

View File

@ -1,5 +1,5 @@
/*
* $Id: StdAwk.hpp 461 2011-05-18 02:32:39Z hyunghwan.chung $
* $Id: StdAwk.hpp 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -142,6 +142,7 @@ protected:
const char_t* fmt, va_list arg);
real_t pow (real_t x, real_t y);
real_t mod (real_t x, real_t y);
real_t sin (real_t x);
real_t cos (real_t x);
real_t tan (real_t x);

View File

@ -1,5 +1,5 @@
/*
* $Id: awk.h 510 2011-07-20 16:17:16Z hyunghwan.chung $
* $Id: awk.h 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -587,6 +587,7 @@ struct qse_awk_prm_t
struct
{
qse_awk_math2_t pow;
qse_awk_math2_t mod;
qse_awk_math1_t sin;
qse_awk_math1_t cos;
qse_awk_math1_t tan;

View File

@ -54,6 +54,15 @@
/* Define to 1 if you have the `expl' function. */
#undef HAVE_EXPL
/* Define to 1 if you have the `fmod' function. */
#undef HAVE_FMOD
/* Define to 1 if you have the `fmodf' function. */
#undef HAVE_FMODF
/* Define to 1 if you have the `fmodl' function. */
#undef HAVE_FMODL
/* Define to 1 if you have the `fstat64' function. */
#undef HAVE_FSTAT64

View File

@ -1,5 +1,5 @@
/*
* $Id: Awk.cpp 510 2011-07-20 16:17:16Z hyunghwan.chung $
* $Id: Awk.cpp 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -1073,6 +1073,7 @@ int Awk::open ()
memset (&prm, 0, QSE_SIZEOF(prm));
prm.sprintf = sprintf;
prm.math.pow = pow;
prm.math.mod = mod;
prm.math.sin = sin;
prm.math.cos = cos;
prm.math.tan = tan;
@ -1752,6 +1753,12 @@ Awk::real_t Awk::pow (awk_t* awk, real_t x, real_t y)
return xtn->awk->pow (x, y);
}
Awk::real_t Awk::mod (awk_t* awk, real_t x, real_t y)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->mod (x, y);
}
Awk::real_t Awk::sin (awk_t* awk, real_t x)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);

View File

@ -1,5 +1,5 @@
/*
* $Id: StdAwk.cpp 510 2011-07-20 16:17:16Z hyunghwan.chung $
* $Id: StdAwk.cpp 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -659,6 +659,19 @@ StdAwk::real_t StdAwk::pow (real_t x, real_t y)
#endif
}
StdAwk::real_t StdAwk::mod (real_t x, real_t y)
{
#if defined(HAVE_FMODL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return ::fmodl (x, y);
#elif defined(HAVE_FMOD)
return ::fmod (x, y);
#elif defined(HAVE_FMODF)
return ::fmodf (x, y);
#else
#error ### no fmod function available ###
#endif
}
StdAwk::real_t StdAwk::sin (real_t x)
{
#if defined(HAVE_SINL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)

View File

@ -1,5 +1,5 @@
/*
* $Id: parse.c 514 2011-07-22 15:37:46Z hyunghwan.chung $
* $Id: parse.c 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -3334,6 +3334,101 @@ static qse_awk_nde_t* parse_expr_dc (
return nde;
}
#define INT_BINOP_INT(x,op,y) \
(((qse_awk_nde_int_t*)x)->val op ((qse_awk_nde_int_t*)y)->val)
#define INT_BINOP_REAL(x,op,y) \
(((qse_awk_nde_int_t*)x)->val op ((qse_awk_nde_real_t*)y)->val)
#define REAL_BINOP_REAL(x,op,y) \
(((qse_awk_nde_real_t*)x)->val op ((qse_awk_nde_real_t*)y)->val)
#if 0
static qse_awk_nde_t* fold_constants_for_binop (
qse_awk_nde_t* left, qse_awk_nde_t* right, int opcode)
{
int fold = 0;
qse_long_t folded_l;
qse_real_t folded_r;
if (left->type == QSE_AWK_NDE_INT &&
right->type == QSE_AWK_NDE_INT)
{
fold = 1;
switch (opcode)
{
case QSE_AWK_BINOP_PLUS:
folded_l = INT_BINOP_INT(left,+,right);
break;
case QSE_AWK_BINOP_MINUS:
folded_l = INT_BINOP_INT(left,-,right);
break;
case QSE_AWK_BINOP_MUL:
folded_l = INT_BINOP_INT(left,*,right);
break;
case QSE_AWK_BINOP_DIV:
if (INT_BINOP_INT(left,%,right))
{
folded_r = (qse_real_t)((qse_awk_nde_int_t*)left)->val /
(qse_real_t)((qse_awk_nde_int_t*)right)->val;
fold = 2;
break;
}
case QSE_AWK_BINOP_IDIV:
folded_l = INT_BINOP_INT(left,/,right);
break;
case QSE_AWK_BINOP_MOD:
folded_l = INT_BINOP_INT(left,%,right);
break;
default:
fold = 0;
break;
}
}
else if (left->type == QSE_AWK_NDE_REAL &&
right->type == QSE_AWK_NDE_REAL)
{
fold = 1;
switch (opcode)
{
case QSE_AWK_BINOP_PLUS:
folded_r = REAL_BINOP_REAL(left,+,right);
break;
case QSE_AWK_BINOP_MINUS:
folded_r = REAL_BINOP_REAL(left,-,right);
break;
case QSE_AWK_BINOP_MUL:
folded_r = REAL_BINOP_REAL(left,*,right);
break;
case QSE_AWK_BINOP_DIV:
folded_r = (qse_real_t)((qse_awk_nde_int_t*)left)->val /
(qse_real_t)((qse_awk_nde_int_t*)right)->val;
break;
case QSE_AWK_BINOP_IDIV:
folded_l = REAL_BINOP_REAL(left,/,right);
break;
case QSE_AWK_BINOP_MOD:
folded_l = REAL_BINOP_REAL(left,%,right);
break;
default:
fold = 0;
break;
}
}
}
#endif
static qse_awk_nde_t* parse_binary (
qse_awk_t* awk, const qse_awk_loc_t* xloc,
int skipnl, const binmap_t* binmap,
@ -3351,8 +3446,6 @@ static qse_awk_nde_t* parse_binary (
qse_awk_loc_t rloc;
const binmap_t* p = binmap;
qse_bool_t matched = QSE_FALSE;
int fold;
qse_long_t folded_l;
while (p->token != TOK_EOF)
{
@ -3384,37 +3477,8 @@ static qse_awk_nde_t* parse_binary (
return QSE_NULL;
}
fold = 0;
if (left->type == QSE_AWK_NDE_INT &&
right->type == QSE_AWK_NDE_INT)
{
fold = 1;
switch (opcode)
{
case QSE_AWK_BINOP_PLUS:
folded_l = ((qse_awk_nde_int_t*)left)->val + ((qse_awk_nde_int_t*)right)->val;
break;
case QSE_AWK_BINOP_MINUS:
folded_l = ((qse_awk_nde_int_t*)left)->val - ((qse_awk_nde_int_t*)right)->val;
break;
case QSE_AWK_BINOP_MUL:
folded_l = ((qse_awk_nde_int_t*)left)->val * ((qse_awk_nde_int_t*)right)->val;
break;
case QSE_AWK_BINOP_IDIV:
folded_l = ((qse_awk_nde_int_t*)left)->val / ((qse_awk_nde_int_t*)right)->val;
break;
case QSE_AWK_BINOP_MOD:
folded_l = ((qse_awk_nde_int_t*)left)->val % ((qse_awk_nde_int_t*)right)->val;
break;
default:
fold = 0;
}
}
#if 0
fold_constants_for_binop (left, right, opcode);
if (fold)
{
@ -3429,6 +3493,7 @@ static qse_awk_nde_t* parse_binary (
}
else
{
#endif
nde = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC (
awk, QSE_SIZEOF(qse_awk_nde_exp_t));
if (nde == QSE_NULL)
@ -3447,7 +3512,9 @@ static qse_awk_nde_t* parse_binary (
nde->right = right;
left = (qse_awk_nde_t*)nde;
#if 0
}
#endif
}
return left;

View File

@ -1,5 +1,5 @@
/*
* $Id: run.c 514 2011-07-22 15:37:46Z hyunghwan.chung $
* $Id: run.c 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -4527,40 +4527,41 @@ static qse_awk_val_t* eval_binop_div (
}
n3 = n1 + (n2 << 1);
if (n3 == 0)
switch (n3)
{
if (l2 == 0)
{
SETERR_COD (rtx, QSE_AWK_EDIVBY0);
return QSE_NULL;
}
case 0:
if (l2 == 0)
{
SETERR_COD (rtx, QSE_AWK_EDIVBY0);
return QSE_NULL;
}
if (((qse_long_t)l1 % (qse_long_t)l2) == 0)
{
res = qse_awk_rtx_makeintval (
rtx, (qse_long_t)l1 / (qse_long_t)l2);
}
else
{
if (((qse_long_t)l1 % (qse_long_t)l2) == 0)
{
res = qse_awk_rtx_makeintval (
rtx, (qse_long_t)l1 / (qse_long_t)l2);
}
else
{
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)l1 / (qse_real_t)l2);
}
break;
case 1:
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)l1 / (qse_real_t)l2);
}
}
else if (n3 == 1)
{
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)r1 / (qse_real_t)l2);
}
else if (n3 == 2)
{
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)l1 / (qse_real_t)r2);
}
else
{
QSE_ASSERT (n3 == 3);
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)r1 / (qse_real_t)r2);
rtx, (qse_real_t)r1 / (qse_real_t)l2);
break;
case 2:
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)l1 / (qse_real_t)r2);
break;
case 3:
res = qse_awk_rtx_makerealval (
rtx, (qse_real_t)r1 / (qse_real_t)r2);
break;
}
return res;
@ -4584,32 +4585,32 @@ static qse_awk_val_t* eval_binop_idiv (
}
n3 = n1 + (n2 << 1);
if (n3 == 0)
switch (n3)
{
if (l2 == 0)
{
SETERR_COD (rtx, QSE_AWK_EDIVBY0);
return QSE_NULL;
}
res = qse_awk_rtx_makeintval (
rtx, (qse_long_t)l1 / (qse_long_t)l2);
}
else if (n3 == 1)
{
quo = (qse_real_t)r1 / (qse_real_t)l2;
res = qse_awk_rtx_makeintval (rtx, (qse_long_t)quo);
}
else if (n3 == 2)
{
quo = (qse_real_t)l1 / (qse_real_t)r2;
res = qse_awk_rtx_makeintval (rtx, (qse_long_t)quo);
}
else
{
QSE_ASSERT (n3 == 3);
case 0:
if (l2 == 0)
{
SETERR_COD (rtx, QSE_AWK_EDIVBY0);
return QSE_NULL;
}
res = qse_awk_rtx_makeintval (
rtx, (qse_long_t)l1 / (qse_long_t)l2);
break;
quo = (qse_real_t)r1 / (qse_real_t)r2;
res = qse_awk_rtx_makeintval (rtx, (qse_long_t)quo);
case 1:
quo = (qse_real_t)r1 / (qse_real_t)l2;
res = qse_awk_rtx_makeintval (rtx, (qse_long_t)quo);
break;
case 2:
quo = (qse_real_t)l1 / (qse_real_t)r2;
res = qse_awk_rtx_makeintval (rtx, (qse_long_t)quo);
break;
case 3:
quo = (qse_real_t)r1 / (qse_real_t)r2;
res = qse_awk_rtx_makeintval (rtx, (qse_long_t)quo);
break;
}
return res;
@ -4623,6 +4624,10 @@ static qse_awk_val_t* eval_binop_mod (
qse_real_t r1, r2;
qse_awk_val_t* res;
QSE_ASSERTX (rtx->awk->prm.math.mod != QSE_NULL,
"the mod function must be provided when the awk object"
" is created to be able to calculate floating-pointer remainder.");
n1 = qse_awk_rtx_valtonum (rtx, left, &l1, &r1);
n2 = qse_awk_rtx_valtonum (rtx, right, &l2, &r2);
@ -4633,20 +4638,38 @@ static qse_awk_val_t* eval_binop_mod (
}
n3 = n1 + (n2 << 1);
if (n3 == 0)
switch (n3)
{
if (l2 == 0)
{
SETERR_COD (rtx, QSE_AWK_EDIVBY0);
return QSE_NULL;
}
res = qse_awk_rtx_makeintval (
rtx, (qse_long_t)l1 % (qse_long_t)l2);
}
else
{
SETERR_COD (rtx, QSE_AWK_EOPERAND);
return QSE_NULL;
case 0:
if (l2 == 0)
{
SETERR_COD (rtx, QSE_AWK_EDIVBY0);
return QSE_NULL;
}
res = qse_awk_rtx_makeintval (
rtx, (qse_long_t)l1 % (qse_long_t)l2);
break;
case 1:
res = qse_awk_rtx_makerealval (rtx,
rtx->awk->prm.math.mod (
rtx->awk, (qse_real_t)r1, (qse_real_t)l2)
);
break;
case 2:
res = qse_awk_rtx_makerealval (rtx,
rtx->awk->prm.math.mod (
rtx->awk, (qse_real_t)l1, (qse_real_t)r2)
);
break;
case 3:
res = qse_awk_rtx_makerealval (rtx,
rtx->awk->prm.math.mod (
rtx->awk, (qse_real_t)r1, (qse_real_t)r2)
);
break;
}
return res;
@ -4661,8 +4684,8 @@ static qse_awk_val_t* eval_binop_exp (
qse_awk_val_t* res;
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.");
"the pow function must be provided when the awk object"
" is created to make exponentiation work properly.");
n1 = qse_awk_rtx_valtonum (rtx, left, &l1, &r1);
n2 = qse_awk_rtx_valtonum (rtx, right, &l2, &r2);

View File

@ -1,5 +1,5 @@
/*
* $Id: std.c 510 2011-07-20 16:17:16Z hyunghwan.chung $
* $Id: std.c 516 2011-07-23 09:03:48Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
@ -127,6 +127,19 @@ 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_mod (qse_awk_t* awk, qse_real_t x, qse_real_t y)
{
#if defined(HAVE_FMODL) && (QSE_SIZEOF_LONG_DOUBLE > QSE_SIZEOF_DOUBLE)
return fmodl (x, y);
#elif defined(HAVE_FMOD)
return fmod (x, y);
#elif defined(HAVE_FMODF)
return fmodf (x, y);
#else
#error ### no fmod function available ###
#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)
@ -261,6 +274,7 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
prm.sprintf = custom_awk_sprintf;
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;