diff options
author | Steve Bennett <steveb@workware.net.au> | 2011-07-04 13:54:49 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2011-07-04 13:54:49 +1000 |
commit | f828399b2034b8dfb03d48a8cbff33a1924e1ed7 (patch) | |
tree | 43205694f4a793806330fed2e2f3ecdb4073f688 | |
parent | 411e92fea9621630eb350e0c2bb43543e553b84f (diff) | |
download | jimtcl-f828399b2034b8dfb03d48a8cbff33a1924e1ed7.zip jimtcl-f828399b2034b8dfb03d48a8cbff33a1924e1ed7.tar.gz jimtcl-f828399b2034b8dfb03d48a8cbff33a1924e1ed7.tar.bz2 |
Add rand() and srand() functions
For Tcl compatibility
Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r-- | jim.c | 41 |
1 files changed, 31 insertions, 10 deletions
@@ -130,6 +130,9 @@ static int JimEvalObjVector(Jim_Interp *interp, int objc, Jim_Obj *const *objv, static int JimGetWideNoErr(Jim_Interp *interp, Jim_Obj *objPtr, jim_wide * widePtr); static int JimSign(jim_wide w); static int JimValidName(Jim_Interp *interp, const char *type, Jim_Obj *nameObjPtr); +static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen); +static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len); + static const Jim_HashTableType JimVariablesHashTableType; @@ -6917,6 +6920,8 @@ enum JIM_EXPROP_FUNC_ABS, JIM_EXPROP_FUNC_DOUBLE, JIM_EXPROP_FUNC_ROUND, + JIM_EXPROP_FUNC_RAND, + JIM_EXPROP_FUNC_SRAND, #ifdef JIM_MATH_FUNCTIONS /* math functions from libm */ @@ -7050,25 +7055,32 @@ static int JimExprOpNumUnary(Jim_Interp *interp, struct JimExprState *e) return rc; } +static double JimRandDouble(Jim_Interp *interp) +{ + unsigned long x; + JimRandomBytes(interp, &x, sizeof(x)); + + return (double)x / (unsigned long)~0; +} + static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) { Jim_Obj *A = ExprPop(e); jim_wide wA; - int rc = JIM_ERR; - - - if (Jim_GetWide(interp, A, &wA) == JIM_OK) { - jim_wide wC; + int rc = Jim_GetWide(interp, A, &wA); + if (rc == JIM_OK) { switch (e->opcode) { case JIM_EXPROP_BITNOT: - wC = ~wA; + ExprPush(e, Jim_NewIntObj(interp, ~wA)); + break; + case JIM_EXPROP_FUNC_SRAND: + JimPrngSeed(interp, (unsigned char *)&wA, sizeof(wA)); + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); break; default: abort(); } - ExprPush(e, Jim_NewIntObj(interp, wC)); - rc = JIM_OK; } Jim_DecrRefCount(interp, A); @@ -7076,6 +7088,15 @@ static int JimExprOpIntUnary(Jim_Interp *interp, struct JimExprState *e) return rc; } +static int JimExprOpNone(Jim_Interp *interp, struct JimExprState *e) +{ + JimPanic((e->opcode != JIM_EXPROP_FUNC_RAND)); + + ExprPush(e, Jim_NewDoubleObj(interp, JimRandDouble(interp))); + + return JIM_OK; +} + #ifdef JIM_MATH_FUNCTIONS static int JimExprOpDoubleUnary(Jim_Interp *interp, struct JimExprState *e) { @@ -7639,6 +7660,8 @@ static const struct Jim_ExprOperator Jim_ExprOperators[] = { [JIM_EXPROP_FUNC_DOUBLE] = {"double", 400, 1, JimExprOpNumUnary, LAZY_NONE}, [JIM_EXPROP_FUNC_ABS] = {"abs", 400, 1, JimExprOpNumUnary, LAZY_NONE}, [JIM_EXPROP_FUNC_ROUND] = {"round", 400, 1, JimExprOpNumUnary, LAZY_NONE}, + [JIM_EXPROP_FUNC_RAND] = {"rand", 400, 0, JimExprOpNone, LAZY_NONE}, + [JIM_EXPROP_FUNC_SRAND] = {"srand", 400, 1, JimExprOpIntUnary, LAZY_NONE}, #ifdef JIM_MATH_FUNCTIONS [JIM_EXPROP_FUNC_SIN] = {"sin", 400, 1, JimExprOpDoubleUnary, LAZY_NONE}, @@ -9327,8 +9350,6 @@ Jim_Obj *Jim_ScanString(Jim_Interp *interp, Jim_Obj *strObjPtr, Jim_Obj *fmtObjP /* ----------------------------------------------------------------------------- * Pseudo Random Number Generation * ---------------------------------------------------------------------------*/ -static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen); - /* Initialize the sbox with the numbers from 0 to 255 */ static void JimPrngInit(Jim_Interp *interp) { |