Aer Interpreter Source
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

8754 lines
242 KiB

/*
* Symisc PH7: An embeddable bytecode compiler and a virtual machine for the PHP(5) programming language.
* Copyright (C) 2011-2012, Symisc Systems http://ph7.symisc.net/
* Version 2.1.4
* For information on licensing,redistribution of this file,and for a DISCLAIMER OF ALL WARRANTIES
* please contact Symisc Systems via:
* legal@symisc.net
* licensing@symisc.net
* contact@symisc.net
* or visit:
* http://ph7.symisc.net/
*/
/* $SymiscID: builtin.c v1.0 FreeBSD 2012-08-06 08:39 devel <chm@symisc.net> $ */
#include "ph7int.h"
/* This file implement built-in 'foreign' functions for the PH7 engine */
/*
* Section:
* Variable handling Functions.
* Authors:
* Symisc Systems,devel@symisc.net.
* Copyright (C) Symisc Systems,http://ph7.symisc.net
* Status:
* Stable.
*/
/*
* bool is_bool($var)
* Finds out whether a variable is a boolean.
* Parameters
* $var: The variable being evaluated.
* Return
* TRUE if var is a boolean. False otherwise.
*/
static int PH7_builtin_is_bool(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_bool(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_float($var)
* bool is_real($var)
* bool is_double($var)
* Finds out whether a variable is a float.
* Parameters
* $var: The variable being evaluated.
* Return
* TRUE if var is a float. False otherwise.
*/
static int PH7_builtin_is_float(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_float(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_int($var)
* bool is_integer($var)
* bool is_long($var)
* Finds out whether a variable is an integer.
* Parameters
* $var: The variable being evaluated.
* Return
* TRUE if var is an integer. False otherwise.
*/
static int PH7_builtin_is_int(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_int(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_string($var)
* Finds out whether a variable is a string.
* Parameters
* $var: The variable being evaluated.
* Return
* TRUE if var is string. False otherwise.
*/
static int PH7_builtin_is_string(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_string(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_null($var)
* Finds out whether a variable is NULL.
* Parameters
* $var: The variable being evaluated.
* Return
* TRUE if var is NULL. False otherwise.
*/
static int PH7_builtin_is_null(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_null(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_numeric($var)
* Find out whether a variable is NULL.
* Parameters
* $var: The variable being evaluated.
* Return
* True if var is numeric. False otherwise.
*/
static int PH7_builtin_is_numeric(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_numeric(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_scalar($var)
* Find out whether a variable is a scalar.
* Parameters
* $var: The variable being evaluated.
* Return
* True if var is scalar. False otherwise.
*/
static int PH7_builtin_is_scalar(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_scalar(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_array($var)
* Find out whether a variable is an array.
* Parameters
* $var: The variable being evaluated.
* Return
* True if var is an array. False otherwise.
*/
static int PH7_builtin_is_array(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_array(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_object($var)
* Find out whether a variable is an object.
* Parameters
* $var: The variable being evaluated.
* Return
* True if var is an object. False otherwise.
*/
static int PH7_builtin_is_object(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_object(apArg[0]);
}
/* Query result */
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* bool is_resource($var)
* Find out whether a variable is a resource.
* Parameters
* $var: The variable being evaluated.
* Return
* True if a resource. False otherwise.
*/
static int PH7_builtin_is_resource(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 0; /* Assume false by default */
if( nArg > 0 ){
res = ph7_value_is_resource(apArg[0]);
}
ph7_result_bool(pCtx,res);
return PH7_OK;
}
/*
* float floatval($var)
* Get float value of a variable.
* Parameter
* $var: The variable being processed.
* Return
* the float value of a variable.
*/
static int PH7_builtin_floatval(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
if( nArg < 1 ){
/* return 0.0 */
ph7_result_double(pCtx,0);
}else{
double dval;
/* Perform the cast */
dval = ph7_value_to_double(apArg[0]);
ph7_result_double(pCtx,dval);
}
return PH7_OK;
}
/*
* int intval($var)
* Get integer value of a variable.
* Parameter
* $var: The variable being processed.
* Return
* the int value of a variable.
*/
static int PH7_builtin_intval(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
if( nArg < 1 ){
/* return 0 */
ph7_result_int(pCtx,0);
}else{
sxi64 iVal;
/* Perform the cast */
iVal = ph7_value_to_int64(apArg[0]);
ph7_result_int64(pCtx,iVal);
}
return PH7_OK;
}
/*
* string strval($var)
* Get the string representation of a variable.
* Parameter
* $var: The variable being processed.
* Return
* the string value of a variable.
*/
static int PH7_builtin_strval(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
if( nArg < 1 ){
/* return NULL */
ph7_result_null(pCtx);
}else{
const char *zVal;
int iLen = 0; /* cc -O6 warning */
/* Perform the cast */
zVal = ph7_value_to_string(apArg[0],&iLen);
ph7_result_string(pCtx,zVal,iLen);
}
return PH7_OK;
}
/*
* bool empty($var)
* Determine whether a variable is empty.
* Parameters
* $var: The variable being checked.
* Return
* 0 if var has a non-empty and non-zero value.1 otherwise.
*/
static int PH7_builtin_empty(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int res = 1; /* Assume empty by default */
if( nArg > 0 ){
res = ph7_value_is_empty(apArg[0]);
}
ph7_result_bool(pCtx,res);
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 <stdlib.h> /* abs */
#include <math.h>
/*
* 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.
* Parameter
* $val
* The value to round.
* $precision
* The optional number of decimal digits to round to.
* $mode
* One of PHP_ROUND_HALF_UP, PHP_ROUND_HALF_DOWN, PHP_ROUND_HALF_EVEN, or PHP_ROUND_HALF_ODD.
* (not supported).
* Return
* The rounded value.
*/
static int PH7_builtin_round(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int n = 0;
double r;
if( nArg < 1 ){
/* Missing argument,return 0 */
ph7_result_int(pCtx,0);
return PH7_OK;
}
/* Extract the precision if available */
if( nArg > 1 ){
n = ph7_value_to_int(apArg[1]);
if( n>30 ){
n = 30;
}
if( n<0 ){
n = 0;
}
}
r = ph7_value_to_double(apArg[0]);
/* If Y==0 and X will fit in a 64-bit int,
* handle the rounding directly.Otherwise
* use our own cutsom printf [i.e:SyBufferFormat()].
*/
if( n==0 && r>=0 && r<LARGEST_INT64-1 ){
r = (double)((ph7_int64)(r+0.5));
}else if( n==0 && r<0 && (-r)<LARGEST_INT64-1 ){
r = -(double)((ph7_int64)((-r)+0.5));
}else{
char zBuf[256];
sxu32 nLen;
nLen = SyBufferFormat(zBuf,sizeof(zBuf),"%.*f",n,r);
/* Convert the string to real number */
SyStrToReal(zBuf,nLen,(void *)&r,0);
}
/* Return thr rounded value */
ph7_result_double(pCtx,r);
return PH7_OK;
}
/*
* string dechex(int $number)
* Decimal to hexadecimal.
* Parameters
* $number
* Decimal value to convert
* Return
* Hexadecimal string representation of number
*/
static int PH7_builtin_dechex(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int iVal;
if( nArg < 1 ){
/* Missing arguments,return null */
ph7_result_null(pCtx);
return PH7_OK;
}
/* Extract the given number */
iVal = ph7_value_to_int(apArg[0]);
/* Format */
ph7_result_string_format(pCtx,"%x",iVal);
return PH7_OK;
}
/*
* string decoct(int $number)
* Decimal to Octal.
* Parameters
* $number
* Decimal value to convert
* Return
* Octal string representation of number
*/
static int PH7_builtin_decoct(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int iVal;
if( nArg < 1 ){
/* Missing arguments,return null */
ph7_result_null(pCtx);
return PH7_OK;
}
/* Extract the given number */
iVal = ph7_value_to_int(apArg[0]);
/* Format */
ph7_result_string_format(pCtx,"%o",iVal);
return PH7_OK;
}
/*
* string decbin(int $number)
* Decimal to binary.
* Parameters
* $number
* Decimal value to convert
* Return
* Binary string representation of number
*/
static int PH7_builtin_decbin(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int iVal;
if( nArg < 1 ){
/* Missing arguments,return null */
ph7_result_null(pCtx);
return PH7_OK;
}
/* Extract the given number */
iVal = ph7_value_to_int(apArg[0]);
/* Format */
ph7_result_string_format(pCtx,"%B",iVal);
return PH7_OK;
}
/*
* int64 hexdec(string $hex_string)
* Hexadecimal to decimal.
* Parameters
* $hex_string
* The hexadecimal string to convert
* Return
* The decimal representation of hex_string
*/
static int PH7_builtin_hexdec(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
const char *zString,*zEnd;
ph7_int64 iVal;
int nLen;
if( nArg < 1 ){
/* Missing arguments,return -1 */
ph7_result_int(pCtx,-1);
return PH7_OK;
}
iVal = 0;
if( ph7_value_is_string(apArg[0]) ){
/* Extract the given string */
zString = ph7_value_to_string(apArg[0],&nLen);
/* Delimit the string */
zEnd = &zString[nLen];
/* Ignore non hex-stream */
while( zString < zEnd ){
if( (unsigned char)zString[0] >= 0xc0 ){
/* UTF-8 stream */
zString++;
while( zString < zEnd && (((unsigned char)zString[0] & 0xc0) == 0x80) ){
zString++;
}
}else{
if( SyisHex(zString[0]) ){
break;
}
/* Ignore */
zString++;
}
}
if( zString < zEnd ){
/* Cast */
SyHexStrToInt64(zString,(sxu32)(zEnd-zString),(void *)&iVal,0);
}
}else{
/* Extract as a 64-bit integer */
iVal = ph7_value_to_int64(apArg[0]);
}
/* Return the number */
ph7_result_int64(pCtx,iVal);
return PH7_OK;
}
/*
* int64 bindec(string $bin_string)
* Binary to decimal.
* Parameters
* $bin_string
* The binary string to convert
* Return
* Returns the decimal equivalent of the binary number represented by the binary_string argument.
*/
static int PH7_builtin_bindec(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
const char *zString;
ph7_int64 iVal;
int nLen;
if( nArg < 1 ){
/* Missing arguments,return -1 */
ph7_result_int(pCtx,-1);
return PH7_OK;
}
iVal = 0;
if( ph7_value_is_string(apArg[0]) ){
/* Extract the given string */
zString = ph7_value_to_string(apArg[0],&nLen);
if( nLen > 0 ){
/* Perform a binary cast */
SyBinaryStrToInt64(zString,(sxu32)nLen,(void *)&iVal,0);
}
}else{
/* Extract as a 64-bit integer */
iVal = ph7_value_to_int64(apArg[0]);
}
/* Return the number */
ph7_result_int64(pCtx,iVal);
return PH7_OK;
}
/*
* int64 octdec(string $oct_string)
* Octal to decimal.
* Parameters
* $oct_string
* The octal string to convert
* Return
* Returns the decimal equivalent of the octal number represented by the octal_string argument.
*/
static int PH7_builtin_octdec(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
const char *zString;
ph7_int64 iVal;
int nLen;
if( nArg < 1 ){
/* Missing arguments,return -1 */
ph7_result_int(pCtx,-1);
return PH7_OK;
}
iVal = 0;
if( ph7_value_is_string(apArg[0]) ){
/* Extract the given string */
zString = ph7_value_to_string(apArg[0],&nLen);
if( nLen > 0 ){
/* Perform the cast */
SyOctalStrToInt64(zString,(sxu32)nLen,(void *)&iVal,0);
}
}else{
/* Extract as a 64-bit integer */
iVal = ph7_value_to_int64(apArg[0]);
}
/* Return the number */
ph7_result_int64(pCtx,iVal);
return PH7_OK;
}
/*
* srand([int $seed])
* mt_srand([int $seed])
* Seed the random number generator.
* Parameters
* $seed
* Optional seed value
* Return
* null.
* Note:
* THIS FUNCTION IS A NO-OP.
* THE PH7 PRNG IS AUTOMATICALLY SEEDED WHEN THE VM IS CREATED.
*/
static int PH7_builtin_srand(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
SXUNUSED(nArg);
SXUNUSED(apArg);
ph7_result_null(pCtx);
return PH7_OK;
}
/*
* string base_convert(string $number,int $frombase,int $tobase)
* Convert a number between arbitrary bases.
* Parameters
* $number
* The number to convert
* $frombase
* The base number is in
* $tobase
* The base to convert number to
* Return
* Number converted to base tobase
*/
static int PH7_builtin_base_convert(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
int nLen,iFbase,iTobase;
const char *zNum;
ph7_int64 iNum;
if( nArg < 3 ){
/* Return the empty string*/
ph7_result_string(pCtx,"",0);
return PH7_OK;
}
/* Base numbers */
iFbase = ph7_value_to_int(apArg[1]);
iTobase = ph7_value_to_int(apArg[2]);
if( ph7_value_is_string(apArg[0]) ){
/* Extract the target number */
zNum = ph7_value_to_string(apArg[0],&nLen);
if( nLen < 1 ){
/* Return the empty string*/
ph7_result_string(pCtx,"",0);
return PH7_OK;
}
/* Base conversion */
switch(iFbase){
case 16:
/* Hex */
SyHexStrToInt64(zNum,(sxu32)nLen,(void *)&iNum,0);
break;
case 8:
/* Octal */
SyOctalStrToInt64(zNum,(sxu32)nLen,(void *)&iNum,0);
break;
case 2:
/* Binary */
SyBinaryStrToInt64(zNum,(sxu32)nLen,(void *)&iNum,0);
break;
default:
/* Decimal */
SyStrToInt64(zNum,(sxu32)nLen,(void *)&iNum,0);
break;
}
}else{
iNum = ph7_value_to_int64(apArg[0]);
}
switch(iTobase){
case 16:
/* Hex */
ph7_result_string_format(pCtx,"%qx",iNum); /* Quad hex */
break;
case 8:
/* Octal */
ph7_result_string_format(pCtx,"%qo",iNum); /* Quad octal */
break;
case 2:
/* Binary */
ph7_result_string_format(pCtx,"%qB",iNum); /* Quad binary */
break;
default:
/* Decimal */
ph7_result_string_format(pCtx,"%qd",iNum); /* Quad decimal */
break;
}
return PH7_OK;
}
/*
* Section:
* String handling Functions.
* Authors:
* Symisc Systems,devel@symisc.net.
* Copyright (C) Symisc Systems,http://ph7.symisc.net
* Status:
* Stable.
*/
/*
* string substr(string $string,int $start[, int $length ])
* Return part of a string.
* Parameters
* $string
* The input string. Must be one character or longer.
* $start
* If start is non-negative, the returned string will start at the start'th position
* in string, counting from zero. For instance, in the string 'abcdef', the character
* at position 0 is 'a', the character at position 2 is 'c', and so forth.
* If start is negative, the returned string will start at the start'th character
* from the end of string.
* If string is less than or equal to start characters long, FALSE will be returned.
* $length
* If length is given and is positive, the string returned will contain at most length
* characters beginning from start (depending on the length of string).
* If length is given and is negative, then that many characters will be omitted from
* the end of string (after the start position has been calculated when a start is negative).
* If start denotes the position of this truncation or beyond, false will be returned.
* If length is given and is 0, FALSE or NULL an empty string will be returned.
* If length is omitted, the substring starting from start until the end of the string
* will be returned.
* Return
* Returns the extracted part of string, or FALSE on failure or an empty string.
*/
static int PH7_builtin_substr(ph7_context *pCtx,int nArg,ph7_value **apArg)
{
const char *zSource,*zOfft;
int nOfft,nLen,nSrcLen;
if( nArg < 2 ){
/* return FALSE */
ph7_result_bool(pCtx,0);