diff --git a/engine/builtin.c b/engine/builtin.c index 889edb6..e279f3b 100644 --- a/engine/builtin.c +++ b/engine/builtin.c @@ -273,507 +273,6 @@ static int PH7_builtin_empty(ph7_context *pCtx, int nArg, ph7_value **apArg) { return PH7_OK; } #ifndef PH7_DISABLE_BUILTIN_FUNC -#ifdef PH7_ENABLE_MATH_FUNC -/* - * Section: - * Math Functions. - * Authors: - * Symisc Systems,devel@symisc.net. - * Copyright (C) Symisc Systems,http://ph7.symisc.net - * Status: - * Stable. - */ -#include /* abs */ -#include -/* - * float sqrt(float $arg ) - * Square root of the given number. - * Parameter - * The number to process. - * Return - * The square root of arg or the special value Nan of failure. - */ -static int PH7_builtin_sqrt(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = sqrt(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float exp(float $arg ) - * Calculates the exponent of e. - * Parameter - * The number to process. - * Return - * 'e' raised to the power of arg. - */ -static int PH7_builtin_exp(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = exp(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float floor(float $arg ) - * Round fractions down. - * Parameter - * The number to process. - * Return - * Returns the next lowest integer value by rounding down value if necessary. - */ -static int PH7_builtin_floor(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = floor(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float cos(float $arg ) - * Cosine. - * Parameter - * The number to process. - * Return - * The cosine of arg. - */ -static int PH7_builtin_cos(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = cos(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float acos(float $arg ) - * Arc cosine. - * Parameter - * The number to process. - * Return - * The arc cosine of arg. - */ -static int PH7_builtin_acos(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = acos(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float cosh(float $arg ) - * Hyperbolic cosine. - * Parameter - * The number to process. - * Return - * The hyperbolic cosine of arg. - */ -static int PH7_builtin_cosh(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = cosh(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float sin(float $arg ) - * Sine. - * Parameter - * The number to process. - * Return - * The sine of arg. - */ -static int PH7_builtin_sin(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = sin(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float asin(float $arg ) - * Arc sine. - * Parameter - * The number to process. - * Return - * The arc sine of arg. - */ -static int PH7_builtin_asin(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = asin(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float sinh(float $arg ) - * Hyperbolic sine. - * Parameter - * The number to process. - * Return - * The hyperbolic sine of arg. - */ -static int PH7_builtin_sinh(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = sinh(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float ceil(float $arg ) - * Round fractions up. - * Parameter - * The number to process. - * Return - * The next highest integer value by rounding up value if necessary. - */ -static int PH7_builtin_ceil(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = ceil(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float tan(float $arg ) - * Tangent. - * Parameter - * The number to process. - * Return - * The tangent of arg. - */ -static int PH7_builtin_tan(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = tan(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float atan(float $arg ) - * Arc tangent. - * Parameter - * The number to process. - * Return - * The arc tangent of arg. - */ -static int PH7_builtin_atan(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = atan(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float tanh(float $arg ) - * Hyperbolic tangent. - * Parameter - * The number to process. - * Return - * The Hyperbolic tangent of arg. - */ -static int PH7_builtin_tanh(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = tanh(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float atan2(float $y,float $x) - * Arc tangent of two variable. - * Parameter - * $y = Dividend parameter. - * $x = Divisor parameter. - * Return - * The arc tangent of y/x in radian. - */ -static int PH7_builtin_atan2(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x, y; - if(nArg < 2) { - /* Missing arguments,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - y = ph7_value_to_double(apArg[0]); - x = ph7_value_to_double(apArg[1]); - /* Perform the requested operation */ - r = atan2(y, x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float/int64 abs(float/int64 $arg ) - * Absolute value. - * Parameter - * The number to process. - * Return - * The absolute value of number. - */ -static int PH7_builtin_abs(ph7_context *pCtx, int nArg, ph7_value **apArg) { - int is_float; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - is_float = ph7_value_is_float(apArg[0]); - if(is_float) { - double r, x; - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = fabs(x); - ph7_result_double(pCtx, r); - } else { - int r, x; - x = ph7_value_to_int(apArg[0]); - /* Perform the requested operation */ - r = abs(x); - ph7_result_int(pCtx, r); - } - return PH7_OK; -} -/* - * float log(float $arg,[int/float $base]) - * Natural logarithm. - * Parameter - * $arg: The number to process. - * $base: The optional logarithmic base to use. (only base-10 is supported) - * Return - * The logarithm of arg to base, if given, or the natural logarithm. - * Note: - * only Natural log and base-10 log are supported. - */ -static int PH7_builtin_log(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - if(nArg == 2 && ph7_value_is_numeric(apArg[1]) && ph7_value_to_int(apArg[1]) == 10) { - /* Base-10 log */ - r = log10(x); - } else { - r = log(x); - } - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float log10(float $arg ) - * Base-10 logarithm. - * Parameter - * The number to process. - * Return - * The Base-10 logarithm of the given number. - */ -static int PH7_builtin_log10(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - /* Perform the requested operation */ - r = log10(x); - /* store the result back */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * number pow(number $base,number $exp) - * Exponential expression. - * Parameter - * base - * The base to use. - * exp - * The exponent. - * Return - * base raised to the power of exp. - * If the result can be represented as integer it will be returned - * as type integer, else it will be returned as type float. - */ -static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double r, x, y; - if(nArg < 1) { - /* Missing argument,return 0 */ - ph7_result_int(pCtx, 0); - return PH7_OK; - } - x = ph7_value_to_double(apArg[0]); - y = ph7_value_to_double(apArg[1]); - /* Perform the requested operation */ - r = pow(x, y); - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float pi(void) - * Returns an approximation of pi. - * Note - * you can use the M_PI constant which yields identical results to pi(). - * Return - * The value of pi as float. - */ -static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg) { - SXUNUSED(nArg); /* cc warning */ - SXUNUSED(apArg); - ph7_result_double(pCtx, PH7_PI); - return PH7_OK; -} -/* - * float fmod(float $x,float $y) - * Returns the floating point remainder (modulo) of the division of the arguments. - * Parameters - * $x - * The dividend - * $y - * The divisor - * Return - * The floating point remainder of x/y. - */ -static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double x, y, r; - if(nArg < 2) { - /* Missing arguments */ - ph7_result_double(pCtx, 0); - return PH7_OK; - } - /* Extract given arguments */ - x = ph7_value_to_double(apArg[0]); - y = ph7_value_to_double(apArg[1]); - /* Perform the requested operation */ - r = fmod(x, y); - /* Processing result */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -/* - * float hypot(float $x,float $y) - * Calculate the length of the hypotenuse of a right-angle triangle . - * Parameters - * $x - * Length of first side - * $y - * Length of first side - * Return - * Calculated length of the hypotenuse. - */ -static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg) { - double x, y, r; - if(nArg < 2) { - /* Missing arguments */ - ph7_result_double(pCtx, 0); - return PH7_OK; - } - /* Extract given arguments */ - x = ph7_value_to_double(apArg[0]); - y = ph7_value_to_double(apArg[1]); - /* Perform the requested operation */ - r = hypot(x, y); - /* Processing result */ - ph7_result_double(pCtx, r); - return PH7_OK; -} -#endif /* PH7_ENABLE_MATH_FUNC */ /* * float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] ) * Exponential expression. @@ -8514,30 +8013,6 @@ static const ph7_builtin_func aBuiltInFunc[] = { { "strval", PH7_builtin_strval }, { "empty", PH7_builtin_empty }, #ifndef PH7_DISABLE_BUILTIN_FUNC -#ifdef PH7_ENABLE_MATH_FUNC - /* Math functions */ - { "abs", PH7_builtin_abs }, - { "sqrt", PH7_builtin_sqrt }, - { "exp", PH7_builtin_exp }, - { "floor", PH7_builtin_floor }, - { "cos", PH7_builtin_cos }, - { "sin", PH7_builtin_sin }, - { "acos", PH7_builtin_acos }, - { "asin", PH7_builtin_asin }, - { "cosh", PH7_builtin_cosh }, - { "sinh", PH7_builtin_sinh }, - { "ceil", PH7_builtin_ceil }, - { "tan", PH7_builtin_tan }, - { "tanh", PH7_builtin_tanh }, - { "atan", PH7_builtin_atan }, - { "atan2", PH7_builtin_atan2 }, - { "log", PH7_builtin_log }, - { "log10", PH7_builtin_log10 }, - { "pow", PH7_builtin_pow }, - { "pi", PH7_builtin_pi }, - { "fmod", PH7_builtin_fmod }, - { "hypot", PH7_builtin_hypot }, -#endif /* PH7_ENABLE_MATH_FUNC */ { "round", PH7_builtin_round }, { "dechex", PH7_builtin_dechex }, { "decoct", PH7_builtin_decoct }, diff --git a/engine/constant.c b/engine/constant.c index 87c31da..a1ca3e5 100644 --- a/engine/constant.c +++ b/engine/constant.c @@ -472,144 +472,6 @@ static void PH7_DBIA_Const(ph7_value *pVal, void *pUserData) { ph7_value_int(pVal, 0x02); /* MUST BE A POWER OF TWO */ SXUNUSED(pUserData); } -#ifdef PH7_ENABLE_MATH_FUNC -/* - * M_PI - * Expand the value of pi. - */ -static void PH7_M_PI_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, PH7_PI); -} -/* - * M_E - * Expand 2.7182818284590452354 - */ -static void PH7_M_E_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 2.7182818284590452354); -} -/* - * M_LOG2E - * Expand 2.7182818284590452354 - */ -static void PH7_M_LOG2E_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.4426950408889634074); -} -/* - * M_LOG10E - * Expand 0.4342944819032518276 - */ -static void PH7_M_LOG10E_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.4342944819032518276); -} -/* - * M_LN2 - * Expand 0.69314718055994530942 - */ -static void PH7_M_LN2_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.69314718055994530942); -} -/* - * M_LN10 - * Expand 2.30258509299404568402 - */ -static void PH7_M_LN10_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 2.30258509299404568402); -} -/* - * M_PI_2 - * Expand 1.57079632679489661923 - */ -static void PH7_M_PI_2_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.57079632679489661923); -} -/* - * M_PI_4 - * Expand 0.78539816339744830962 - */ -static void PH7_M_PI_4_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.78539816339744830962); -} -/* - * M_1_PI - * Expand 0.31830988618379067154 - */ -static void PH7_M_1_PI_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.31830988618379067154); -} -/* - * M_2_PI - * Expand 0.63661977236758134308 - */ -static void PH7_M_2_PI_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.63661977236758134308); -} -/* - * M_SQRTPI - * Expand 1.77245385090551602729 - */ -static void PH7_M_SQRTPI_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.77245385090551602729); -} -/* - * M_2_SQRTPI - * Expand 1.12837916709551257390 - */ -static void PH7_M_2_SQRTPI_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.12837916709551257390); -} -/* - * M_SQRT2 - * Expand 1.41421356237309504880 - */ -static void PH7_M_SQRT2_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.41421356237309504880); -} -/* - * M_SQRT3 - * Expand 1.73205080756887729352 - */ -static void PH7_M_SQRT3_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.73205080756887729352); -} -/* - * M_SQRT1_2 - * Expand 0.70710678118654752440 - */ -static void PH7_M_SQRT1_2_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.70710678118654752440); -} -/* - * M_LNPI - * Expand 1.14472988584940017414 - */ -static void PH7_M_LNPI_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 1.14472988584940017414); -} -/* - * M_EULER - * Expand 0.57721566490153286061 - */ -static void PH7_M_EULER_Const(ph7_value *pVal, void *pUserData) { - SXUNUSED(pUserData); /* cc warning */ - ph7_value_double(pVal, 0.57721566490153286061); -} -#endif /* PH7_DISABLE_BUILTIN_MATH */ /* * DATE_ATOM * Expand Atom (example: 2005-08-15T15:52:01+00:00) @@ -1366,25 +1228,6 @@ static const ph7_builtin_constant aBuiltIn[] = { {"PHP_ROUND_HALF_ODD", PH7_PHP_ROUND_HALF_ODD_Const }, {"DEBUG_BACKTRACE_IGNORE_ARGS", PH7_DBIA_Const }, {"DEBUG_BACKTRACE_PROVIDE_OBJECT", PH7_DBPO_Const}, -#ifdef PH7_ENABLE_MATH_FUNC - {"M_PI", PH7_M_PI_Const }, - {"M_E", PH7_M_E_Const }, - {"M_LOG2E", PH7_M_LOG2E_Const }, - {"M_LOG10E", PH7_M_LOG10E_Const }, - {"M_LN2", PH7_M_LN2_Const }, - {"M_LN10", PH7_M_LN10_Const }, - {"M_PI_2", PH7_M_PI_2_Const }, - {"M_PI_4", PH7_M_PI_4_Const }, - {"M_1_PI", PH7_M_1_PI_Const }, - {"M_2_PI", PH7_M_2_PI_Const }, - {"M_SQRTPI", PH7_M_SQRTPI_Const }, - {"M_2_SQRTPI", PH7_M_2_SQRTPI_Const }, - {"M_SQRT2", PH7_M_SQRT2_Const }, - {"M_SQRT3", PH7_M_SQRT3_Const }, - {"M_SQRT1_2", PH7_M_SQRT1_2_Const }, - {"M_LNPI", PH7_M_LNPI_Const }, - {"M_EULER", PH7_M_EULER_Const }, -#endif /* PH7_ENABLE_MATH_FUNC */ {"DATE_ATOM", PH7_DATE_ATOM_Const }, {"DATE_COOKIE", PH7_DATE_COOKIE_Const }, {"DATE_ISO8601", PH7_DATE_ISO8601_Const }, diff --git a/include/ph7int.h b/include/ph7int.h index d030bdd..ca28d2b 100644 --- a/include/ph7int.h +++ b/include/ph7int.h @@ -20,10 +20,7 @@ #else #include #endif -#ifndef PH7_PI - /* Value of PI */ - #define PH7_PI 3.1415926535898 -#endif + /* * Constants for the largest and smallest possible 64-bit signed integers. * These macros are designed to work correctly on both 32-bit and 64-bit diff --git a/modules/math/math.c b/modules/math/math.c new file mode 100644 index 0000000..6d545d4 --- /dev/null +++ b/modules/math/math.c @@ -0,0 +1,647 @@ +#include "math.h" + +/* + * M_PI + * Expand the value of pi. + */ +static void PH7_M_PI_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, PH7_PI); +} +/* + * M_E + * Expand 2.7182818284590452354 + */ +static void PH7_M_E_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 2.7182818284590452354); +} +/* + * M_LOG2E + * Expand 2.7182818284590452354 + */ +static void PH7_M_LOG2E_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.4426950408889634074); +} +/* + * M_LOG10E + * Expand 0.4342944819032518276 + */ +static void PH7_M_LOG10E_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.4342944819032518276); +} +/* + * M_LN2 + * Expand 0.69314718055994530942 + */ +static void PH7_M_LN2_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.69314718055994530942); +} +/* + * M_LN10 + * Expand 2.30258509299404568402 + */ +static void PH7_M_LN10_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 2.30258509299404568402); +} +/* + * M_PI_2 + * Expand 1.57079632679489661923 + */ +static void PH7_M_PI_2_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.57079632679489661923); +} +/* + * M_PI_4 + * Expand 0.78539816339744830962 + */ +static void PH7_M_PI_4_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.78539816339744830962); +} +/* + * M_1_PI + * Expand 0.31830988618379067154 + */ +static void PH7_M_1_PI_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.31830988618379067154); +} +/* + * M_2_PI + * Expand 0.63661977236758134308 + */ +static void PH7_M_2_PI_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.63661977236758134308); +} +/* + * M_SQRTPI + * Expand 1.77245385090551602729 + */ +static void PH7_M_SQRTPI_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.77245385090551602729); +} +/* + * M_2_SQRTPI + * Expand 1.12837916709551257390 + */ +static void PH7_M_2_SQRTPI_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.12837916709551257390); +} +/* + * M_SQRT2 + * Expand 1.41421356237309504880 + */ +static void PH7_M_SQRT2_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.41421356237309504880); +} +/* + * M_SQRT3 + * Expand 1.73205080756887729352 + */ +static void PH7_M_SQRT3_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.73205080756887729352); +} +/* + * M_SQRT1_2 + * Expand 0.70710678118654752440 + */ +static void PH7_M_SQRT1_2_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.70710678118654752440); +} +/* + * M_LNPI + * Expand 1.14472988584940017414 + */ +static void PH7_M_LNPI_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 1.14472988584940017414); +} +/* + * M_EULER + * Expand 0.57721566490153286061 + */ +static void PH7_M_EULER_Const(ph7_value *pVal, void *pUserData) { + SXUNUSED(pUserData); /* cc warning */ + ph7_value_double(pVal, 0.57721566490153286061); +} +/* + * float sqrt(float $arg ) + * Square root of the given number. + * Parameter + * The number to process. + * Return + * The square root of arg or the special value Nan of failure. + */ +static int PH7_builtin_sqrt(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = sqrt(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float exp(float $arg ) + * Calculates the exponent of e. + * Parameter + * The number to process. + * Return + * 'e' raised to the power of arg. + */ +static int PH7_builtin_exp(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = exp(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float floor(float $arg ) + * Round fractions down. + * Parameter + * The number to process. + * Return + * Returns the next lowest integer value by rounding down value if necessary. + */ +static int PH7_builtin_floor(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = floor(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float cos(float $arg ) + * Cosine. + * Parameter + * The number to process. + * Return + * The cosine of arg. + */ +static int PH7_builtin_cos(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = cos(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float acos(float $arg ) + * Arc cosine. + * Parameter + * The number to process. + * Return + * The arc cosine of arg. + */ +static int PH7_builtin_acos(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = acos(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float cosh(float $arg ) + * Hyperbolic cosine. + * Parameter + * The number to process. + * Return + * The hyperbolic cosine of arg. + */ +static int PH7_builtin_cosh(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = cosh(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float sin(float $arg ) + * Sine. + * Parameter + * The number to process. + * Return + * The sine of arg. + */ +static int PH7_builtin_sin(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = sin(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float asin(float $arg ) + * Arc sine. + * Parameter + * The number to process. + * Return + * The arc sine of arg. + */ +static int PH7_builtin_asin(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = asin(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float sinh(float $arg ) + * Hyperbolic sine. + * Parameter + * The number to process. + * Return + * The hyperbolic sine of arg. + */ +static int PH7_builtin_sinh(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = sinh(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float ceil(float $arg ) + * Round fractions up. + * Parameter + * The number to process. + * Return + * The next highest integer value by rounding up value if necessary. + */ +static int PH7_builtin_ceil(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = ceil(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float tan(float $arg ) + * Tangent. + * Parameter + * The number to process. + * Return + * The tangent of arg. + */ +static int PH7_builtin_tan(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = tan(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float atan(float $arg ) + * Arc tangent. + * Parameter + * The number to process. + * Return + * The arc tangent of arg. + */ +static int PH7_builtin_atan(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = atan(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float tanh(float $arg ) + * Hyperbolic tangent. + * Parameter + * The number to process. + * Return + * The Hyperbolic tangent of arg. + */ +static int PH7_builtin_tanh(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = tanh(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float atan2(float $y,float $x) + * Arc tangent of two variable. + * Parameter + * $y = Dividend parameter. + * $x = Divisor parameter. + * Return + * The arc tangent of y/x in radian. + */ +static int PH7_builtin_atan2(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x, y; + if(nArg < 2) { + /* Missing arguments,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + y = ph7_value_to_double(apArg[0]); + x = ph7_value_to_double(apArg[1]); + /* Perform the requested operation */ + r = atan2(y, x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float/int64 abs(float/int64 $arg ) + * Absolute value. + * Parameter + * The number to process. + * Return + * The absolute value of number. + */ +static int PH7_builtin_abs(ph7_context *pCtx, int nArg, ph7_value **apArg) { + int is_float; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + is_float = ph7_value_is_float(apArg[0]); + if(is_float) { + double r, x; + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = fabs(x); + ph7_result_double(pCtx, r); + } else { + int r, x; + x = ph7_value_to_int(apArg[0]); + /* Perform the requested operation */ + r = abs(x); + ph7_result_int(pCtx, r); + } + return PH7_OK; +} +/* + * float log(float $arg,[int/float $base]) + * Natural logarithm. + * Parameter + * $arg: The number to process. + * $base: The optional logarithmic base to use. (only base-10 is supported) + * Return + * The logarithm of arg to base, if given, or the natural logarithm. + * Note: + * only Natural log and base-10 log are supported. + */ +static int PH7_builtin_log(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + if(nArg == 2 && ph7_value_is_numeric(apArg[1]) && ph7_value_to_int(apArg[1]) == 10) { + /* Base-10 log */ + r = log10(x); + } else { + r = log(x); + } + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float log10(float $arg ) + * Base-10 logarithm. + * Parameter + * The number to process. + * Return + * The Base-10 logarithm of the given number. + */ +static int PH7_builtin_log10(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + /* Perform the requested operation */ + r = log10(x); + /* store the result back */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * number pow(number $base,number $exp) + * Exponential expression. + * Parameter + * base + * The base to use. + * exp + * The exponent. + * Return + * base raised to the power of exp. + * If the result can be represented as integer it will be returned + * as type integer, else it will be returned as type float. + */ +static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double r, x, y; + if(nArg < 1) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + x = ph7_value_to_double(apArg[0]); + y = ph7_value_to_double(apArg[1]); + /* Perform the requested operation */ + r = pow(x, y); + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float pi(void) + * Returns an approximation of pi. + * Note + * you can use the M_PI constant which yields identical results to pi(). + * Return + * The value of pi as float. + */ +static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg) { + SXUNUSED(nArg); /* cc warning */ + SXUNUSED(apArg); + ph7_result_double(pCtx, PH7_PI); + return PH7_OK; +} +/* + * float fmod(float $x,float $y) + * Returns the floating point remainder (modulo) of the division of the arguments. + * Parameters + * $x + * The dividend + * $y + * The divisor + * Return + * The floating point remainder of x/y. + */ +static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double x, y, r; + if(nArg < 2) { + /* Missing arguments */ + ph7_result_double(pCtx, 0); + return PH7_OK; + } + /* Extract given arguments */ + x = ph7_value_to_double(apArg[0]); + y = ph7_value_to_double(apArg[1]); + /* Perform the requested operation */ + r = fmod(x, y); + /* Processing result */ + ph7_result_double(pCtx, r); + return PH7_OK; +} +/* + * float hypot(float $x,float $y) + * Calculate the length of the hypotenuse of a right-angle triangle . + * Parameters + * $x + * Length of first side + * $y + * Length of first side + * Return + * Calculated length of the hypotenuse. + */ +static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg) { + double x, y, r; + if(nArg < 2) { + /* Missing arguments */ + ph7_result_double(pCtx, 0); + return PH7_OK; + } + /* Extract given arguments */ + x = ph7_value_to_double(apArg[0]); + y = ph7_value_to_double(apArg[1]); + /* Perform the requested operation */ + r = hypot(x, y); + /* Processing result */ + ph7_result_double(pCtx, r); + return PH7_OK; +} + +PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc){ + sxi32 rc; + sxu32 n; + + desc->zString = MODULE_DESC; + *ver = MODULE_VER; + for(n = 0; n < SX_ARRAYSIZE(mathConstList); ++n) { + rc = ph7_create_constant(&(*pVm), mathConstList[n].zName, mathConstList[n].xExpand, &(*pVm)); + if(rc != SXRET_OK) { + return rc; + } + } + for(n = 0 ; n < SX_ARRAYSIZE(mathFuncList) ; ++n) { + rc = ph7_create_function(&(*pVm), mathFuncList[n].zName, mathFuncList[n].xFunc, &(*pVm)); + if(rc != SXRET_OK) { + return rc; + } + } + return SXRET_OK; +} diff --git a/modules/math/math.h b/modules/math/math.h new file mode 100644 index 0000000..59be2fe --- /dev/null +++ b/modules/math/math.h @@ -0,0 +1,100 @@ +#ifndef __MATH_H__ +#define __MATH_H__ + +#include +#include + +#include "ph7.h" +#include "ph7int.h" + +#define MODULE_DESC "Math Module" +#define MODULE_VER 1.0 + +#define PH7_PI 3.1415926535898 + +/* Forward reference & declaration */ +static void PH7_M_PI_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_E_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_LOG2E_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_LOG10E_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_LN2_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_LN10_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_PI_2_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_PI_4_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_1_PI_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_2_PI_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_SQRTPI_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_2_SQRTPI_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_SQRT2_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_SQRT3_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_SQRT1_2_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_LNPI_Const(ph7_value *pVal, void *pUserData); +static void PH7_M_EULER_Const(ph7_value *pVal, void *pUserData); +static int PH7_builtin_sqrt(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_exp(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_floor(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_cos(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_acos(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_cosh(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_sin(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_asin(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_sinh(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_ceil(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_tan(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_atan(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_tanh(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_atan2(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_abs(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_log(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_log10(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_pow(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_pi(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_fmod(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg); +PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc); + +static const ph7_builtin_constant mathConstList[] = { + {"M_PI", PH7_M_PI_Const }, + {"M_E", PH7_M_E_Const }, + {"M_LOG2E", PH7_M_LOG2E_Const }, + {"M_LOG10E", PH7_M_LOG10E_Const }, + {"M_LN2", PH7_M_LN2_Const }, + {"M_LN10", PH7_M_LN10_Const }, + {"M_PI_2", PH7_M_PI_2_Const }, + {"M_PI_4", PH7_M_PI_4_Const }, + {"M_1_PI", PH7_M_1_PI_Const }, + {"M_2_PI", PH7_M_2_PI_Const }, + {"M_SQRTPI", PH7_M_SQRTPI_Const }, + {"M_2_SQRTPI", PH7_M_2_SQRTPI_Const }, + {"M_SQRT2", PH7_M_SQRT2_Const }, + {"M_SQRT3", PH7_M_SQRT3_Const }, + {"M_SQRT1_2", PH7_M_SQRT1_2_Const }, + {"M_LNPI", PH7_M_LNPI_Const }, + {"M_EULER", PH7_M_EULER_Const } +}; + +static const ph7_builtin_func mathFuncList[] = { + { "abs", PH7_builtin_abs }, + { "sqrt", PH7_builtin_sqrt }, + { "exp", PH7_builtin_exp }, + { "floor", PH7_builtin_floor }, + { "cos", PH7_builtin_cos }, + { "sin", PH7_builtin_sin }, + { "acos", PH7_builtin_acos }, + { "asin", PH7_builtin_asin }, + { "cosh", PH7_builtin_cosh }, + { "sinh", PH7_builtin_sinh }, + { "ceil", PH7_builtin_ceil }, + { "tan", PH7_builtin_tan }, + { "tanh", PH7_builtin_tanh }, + { "atan", PH7_builtin_atan }, + { "atan2", PH7_builtin_atan2 }, + { "log", PH7_builtin_log }, + { "log10", PH7_builtin_log10 }, + { "pow", PH7_builtin_pow }, + { "pi", PH7_builtin_pi }, + { "fmod", PH7_builtin_fmod }, + { "hypot", PH7_builtin_hypot } +}; + +#endif