| | 357 | static unsigned long _clockSeed() |
| | 358 | { |
| | 359 | unsigned long seed; |
| | 360 | seed = time(NULL); |
| | 361 | seed += clock(); |
| | 362 | return seed; |
| | 363 | } |
| | 364 | |
| | 365 | |
| | 366 | /* |
| | 367 | (max -- n) |
| | 368 | (n 'seed -- ) |
| | 369 | */ |
| | 370 | UR_CALL( uc_random ) |
| | 371 | { |
| | 372 | if( ur_is(tos, UT_DECIMAL) ) |
| | 373 | { |
| | 374 | ur_decimal(tos) *= genrand_real2(); |
| | 375 | } |
| | 376 | else if( ur_is(tos, UT_INT) ) |
| | 377 | { |
| | 378 | ur_int(tos) = (genrand_int32() % ur_int(tos)) + 1; |
| | 379 | } |
| | 380 | else if( ur_isASeries( tos ) ) |
| | 381 | { |
| | 382 | int len = ur_seriesLen( tos ); |
| | 383 | if( len < 0 ) |
| | 384 | goto bad_type; |
| | 385 | if( len > 0 ) |
| | 386 | tos->series.it += genrand_int32() % (len - tos->series.it); |
| | 387 | } |
| | 388 | else if( ur_is(tos, UT_LOGIC) ) |
| | 389 | { |
| | 390 | ur_logic(tos) = genrand_int32() & 1; |
| | 391 | } |
| | 392 | else if( ur_isAWord(tos) ) |
| | 393 | { |
| | 394 | unsigned long seed; |
| | 395 | |
| | 396 | tos = ur_s_prev(tos); |
| | 397 | |
| | 398 | if( ur_is(tos, UT_INT) && ur_int(tos) ) |
| | 399 | seed = ur_int(tos); |
| | 400 | else |
| | 401 | seed = _clockSeed(); |
| | 402 | init_genrand( seed ); |
| | 403 | |
| | 404 | UR_S_DROPN( 2 ); |
| | 405 | } |
| | 406 | else |
| | 407 | { |
| | 408 | bad_type: |
| | 409 | ur_throwErr( UR_ERR_DATATYPE, "random does not handle %s", |
| | 410 | ur_typeName( ur_type(tos) ) ); |
| | 411 | } |
| | 412 | } |
| | 413 | |
| | 414 | |
| 363 | | #define REF_RAND_SEED a1+1 |
| 364 | | #define REF_RAND_ONLY a1+2 |
| 365 | | |
| 366 | | /* NOTE: random does not follow REBOL behavior. */ |
| 367 | | UR_CALL( orRandomNative ) |
| 368 | | { |
| 369 | | if( orRefineSet(REF_RAND_SEED) ) |
| 370 | | { |
| 371 | | unsigned long seed; |
| 372 | | if( ur_int(a1) ) |
| 373 | | seed = ur_int(a1); |
| 374 | | else |
| 375 | | seed = randomSeed(); |
| 376 | | init_genrand( seed ); |
| 377 | | } |
| 378 | | else |
| 379 | | { |
| 380 | | if( orIsSeries( orType(a1) ) ) |
| 381 | | { |
| 382 | | if( orRefineSet(REF_RAND_ONLY) ) |
| 383 | | { |
| 384 | | ur_throwErr( "random/only not yet implemented " ); |
| 385 | | return; |
| 386 | | } |
| 387 | | else |
| 388 | | { |
| 389 | | unsigned long rn; |
| 390 | | int used; |
| 391 | | |
| 392 | | used = orSeriesUsed( a1 ); |
| 393 | | if( used > -1 ) |
| 394 | | { |
| 395 | | rn = genrand_int32(); |
| 396 | | used -= a1->series.it; |
| 397 | | a1->series.it += rn % used; |
| 398 | | return; |
| 399 | | } |
| 400 | | } |
| 401 | | } |
| 402 | | else if( orIs(a1, UT_DECIMAL) ) |
| 403 | | { |
| 404 | | ur_decimal(a1) *= genrand_real2(); |
| 405 | | return; |
| 406 | | } |
| 407 | | else if( orIs(a1, UT_INT) ) |
| 408 | | { |
| 409 | | unsigned long rn = genrand_int32(); |
| 410 | | ur_int(a1) = (rn % ur_int(a1)) + 1; |
| 411 | | return; |
| 412 | | } |
| 413 | | else if( orIs(a1, UT_LOGIC) ) |
| 414 | | { |
| 415 | | ur_int(a1) = genrand_int32() & 1; |
| 416 | | return; |
| 417 | | } |
| 418 | | /* |
| 419 | | else if( a1->type == UT_TUPLE ) |
| 420 | | { |
| 421 | | } |
| 422 | | */ |
| 423 | | } |
| 424 | | ur_throwErr( "random does not handle %s", orDatatypeName(a1->type) ); |
| 425 | | } |
| 426 | | |
| 427 | | |