From af139b3f0a5c65969da65b2c77cd294245d7086a Mon Sep 17 00:00:00 2001 From: belliash Date: Wed, 15 Aug 2018 17:26:26 +0200 Subject: [PATCH] Reimplement C-like min() and max() functions. These functions should have C-like implementation and take exactly 2 arguments: integer or float. Finally, C-implementation will be faster than using PH7 builtin library that needs to be compiled and interpreted. --- engine/vm.c | 64 --------------------------------------------- modules/math/math.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ modules/math/math.h | 6 ++++- 3 files changed, 69 insertions(+), 65 deletions(-) diff --git a/engine/vm.c b/engine/vm.c index 559e8ab..d7df441 100644 --- a/engine/vm.c +++ b/engine/vm.c @@ -1089,70 +1089,6 @@ static sxi32 VmEvalChunk(ph7_vm *pVm, ph7_context *pCtx, SyString *pChunk, int i "}"\ " return $ret;"\ "}"\ - "function max(){"\ - " $pArgs = func_get_args();"\ - " if( sizeof($pArgs) < 1 ){"\ - " return null;"\ - " }"\ - " if( sizeof($pArgs) < 2 ){"\ - " $pArg = $pArgs[0];"\ - " if( !is_array($pArg) ){"\ - " return $pArg; "\ - " }"\ - " if( sizeof($pArg) < 1 ){"\ - " return null;"\ - " }"\ - " $pArg = array_copy($pArgs[0]);"\ - " reset($pArg);"\ - " $max = current($pArg);"\ - " while( FALSE !== ($val = next($pArg)) ){"\ - " if( $val > $max ){"\ - " $max = $val;"\ - " }"\ - " }"\ - " return $max;"\ - " }"\ - " $max = $pArgs[0];"\ - " for( $i = 1; $i < sizeof($pArgs) ; ++$i ){"\ - " $val = $pArgs[$i];"\ - "if( $val > $max ){"\ - " $max = $val;"\ - "}"\ - " }"\ - " return $max;"\ - "}"\ - "function min(){"\ - " $pArgs = func_get_args();"\ - " if( sizeof($pArgs) < 1 ){"\ - " return null;"\ - " }"\ - " if( sizeof($pArgs) < 2 ){"\ - " $pArg = $pArgs[0];"\ - " if( !is_array($pArg) ){"\ - " return $pArg; "\ - " }"\ - " if( sizeof($pArg) < 1 ){"\ - " return null;"\ - " }"\ - " $pArg = array_copy($pArgs[0]);"\ - " reset($pArg);"\ - " $min = current($pArg);"\ - " while( FALSE !== ($val = next($pArg)) ){"\ - " if( $val < $min ){"\ - " $min = $val;"\ - " }"\ - " }"\ - " return $min;"\ - " }"\ - " $min = $pArgs[0];"\ - " for( $i = 1; $i < sizeof($pArgs) ; ++$i ){"\ - " $val = $pArgs[$i];"\ - "if( $val < $min ){"\ - " $min = $val;"\ - " }"\ - " }"\ - " return $min;"\ - "}"\ "function fileowner(string $file){"\ " $a = stat($file);"\ " if( !is_array($a) ){"\ diff --git a/modules/math/math.c b/modules/math/math.c index 0425323..53f6ea3 100644 --- a/modules/math/math.c +++ b/modules/math/math.c @@ -624,6 +624,70 @@ static int PH7_builtin_hypot(ph7_context *pCtx, int nArg, ph7_value **apArg) { ph7_result_double(pCtx, r); return PH7_OK; } +/* + * float/int64 max(float/int64 $arg ) + * Absolute value. + * Parameter + * The number to process. + * Return + * The absolute value of number. + */ +static int PH7_builtin_max(ph7_context *pCtx, int nArg, ph7_value **apArg) { + if(nArg < 2) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + if(ph7_value_is_float(apArg[0]) && ph7_value_is_float(apArg[1])) { + double a, b; + a = ph7_value_to_double(apArg[0]); + b = ph7_value_to_double(apArg[1]); + /* Perform the requested operation */ + ph7_result_double(pCtx, SXMAX(a, b)); + } else if(ph7_value_is_int(apArg[0]) && ph7_value_is_int(apArg[1])) { + sxi64 a, b; + a = ph7_value_to_int64(apArg[0]); + b = ph7_value_to_int64(apArg[1]); + /* Perform the requested operation */ + ph7_result_int64(pCtx, SXMAX(a, b)); + } else { + /* Two parameters of different type */ + ph7_result_int(pCtx, 0); + } + return PH7_OK; +} +/* + * float/int64 min(float/int64 $arg ) + * Absolute value. + * Parameter + * The number to process. + * Return + * The absolute value of number. + */ +static int PH7_builtin_min(ph7_context *pCtx, int nArg, ph7_value **apArg) { + if(nArg < 2) { + /* Missing argument,return 0 */ + ph7_result_int(pCtx, 0); + return PH7_OK; + } + if(ph7_value_is_float(apArg[0]) && ph7_value_is_float(apArg[1])) { + double a, b; + a = ph7_value_to_double(apArg[0]); + b = ph7_value_to_double(apArg[1]); + /* Perform the requested operation */ + ph7_result_double(pCtx, SXMIN(a, b)); + } else if(ph7_value_is_int(apArg[0]) && ph7_value_is_int(apArg[1])) { + sxi64 a, b; + a = ph7_value_to_int64(apArg[0]); + b = ph7_value_to_int64(apArg[1]); + /* Perform the requested operation */ + ph7_result_int64(pCtx, SXMIN(a, b)); + } else { + /* Two parameters of different type */ + ph7_result_int(pCtx, 0); + } + return PH7_OK; +} PH7_PRIVATE sxi32 initializeModule(ph7_vm *pVm, ph7_real *ver, SyString *desc) { sxi32 rc; diff --git a/modules/math/math.h b/modules/math/math.h index 59be2fe..8a5e2dd 100644 --- a/modules/math/math.h +++ b/modules/math/math.h @@ -51,6 +51,8 @@ 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); +static int PH7_builtin_max(ph7_context *pCtx, int nArg, ph7_value **apArg); +static int PH7_builtin_min(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[] = { @@ -94,7 +96,9 @@ static const ph7_builtin_func mathFuncList[] = { { "pow", PH7_builtin_pow }, { "pi", PH7_builtin_pi }, { "fmod", PH7_builtin_fmod }, - { "hypot", PH7_builtin_hypot } + { "hypot", PH7_builtin_hypot }, + { "max", PH7_builtin_max }, + { "min", PH7_builtin_min } }; #endif