A simple implementation of rand() and srand() which may not be ideal for Perl. Also included is the test file for random ops. If anyone can think of a good way to ALWAYS know that a number we got back was "random", throw that into the test ;-)
Perl 5 mandates that it calls srand if you call rand without first calling srand. Since not all Parrot client-languages will want that behavior it's not in this version of rand, but that leaves Perl having to maintain separate state. In future, it would be nice to add a special "rsrand" or the like, which checks to see if srand has already been called. For now this should be sufficient for anyone who expects a rand op, and it's not an onerous amount of state for Perl to store. The real concern is that Perl and Foolanguage might both srand(), but that's not something I'm gonna think too hard about just now and probably is a matter for library maintainers in those languages anyway. Oh, one more thing: I added op numbers for the sqrt ops since they were causing me to be given some warnings during build. Feel free to ignore them if you don't want sqrt to have op numbers. -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback
Index: ops/math.ops =================================================================== RCS file: /cvs/public/parrot/ops/math.ops,v retrieving revision 1.18 diff -u -r1.18 math.ops --- ops/math.ops 27 Apr 2004 15:48:20 -0000 1.18 +++ ops/math.ops 27 Apr 2004 20:10:16 -0000 @@ -1392,6 +1392,58 @@ =back +=item B<rand>(out NUM, in NUM) + +=item B<rand>(out NUM) + +=item B<rand>(out INT, in INT) + +=item B<rand>(out INT) + +=item B<srand>(in NUM) + +Generate random numbers based on the Random PMC. + +=cut + +inline op rand(out NUM, in NUM) { + FLOATVAL n = $2; + PMC * r = pmc_new_noinit(interpreter, enum_class_Random); + $1 = VTABLE_get_number(interpreter,r); + $1 *= $2; + goto NEXT(); +} + +inline op rand(out INT, in INT) { + INTVAL n = $2; + PMC * r = pmc_new_noinit(interpreter, enum_class_Random); + FLOATVAL resultnum; + resultnum = VTABLE_get_number(interpreter,r); + $1 = (INTVAL)(resultnum * (FLOATVAL)n); + goto NEXT(); +} + +inline op rand(out NUM) { + PMC * r = pmc_new_noinit(interpreter, enum_class_Random); + $1 = VTABLE_get_number(interpreter,r); + goto NEXT(); +} + +inline op rand(out INT) { + PMC *r = pmc_new_noinit(interpreter, enum_class_Random); + $1 = VTABLE_get_integer(interpreter,r); + goto NEXT(); +} + +inline op srand(in INT) { + INTVAL i = $1; + PMC * r = pmc_new_noinit(interpreter, enum_class_Random); + VTABLE_set_integer_native(interpreter,r,i); + goto NEXT(); +} + +=back + =cut ############################################################################### Index: ops/ops.num =================================================================== RCS file: /cvs/public/parrot/ops/ops.num,v retrieving revision 1.36 diff -u -r1.36 ops.num --- ops/ops.num 22 Apr 2004 09:17:38 -0000 1.36 +++ ops/ops.num 27 Apr 2004 20:10:16 -0000 @@ -1451,3 +1451,15 @@ fetchmethod_p_p_s 1424 fetchmethod_p_p_sc 1425 setref_p_p 1426 +sqrt_n_i 1427 +sqrt_n_ic 1428 +sqrt_n_n 1429 +sqrt_n_nc 1430 +rand_n_n 1431 +rand_n_nc 1432 +rand_i_i 1433 +rand_i_ic 1434 +rand_n 1435 +rand_i 1436 +srand_i 1437 +srand_ic 1438
#! perl -w # Copyright: 2001-2003 The Perl Foundation. All Rights Reserved. # $Id$ =head1 NAME t/op/random.t - Random numbers =head1 SYNOPSIS % perl t/op/random.t =head1 DESCRIPTION Tests random number generation =cut use Parrot::Test tests => 5; use Test::More; use Parrot::Config; use Config; output_is(<<'CODE', <<OUT, "generate random int"); rand I0 print "Called random just fine\n" end CODE Called random just fine OUT output_is(<<'CODE', <<OUT, "generate random 10>int>=0"); rand I0, 10 ge I0, 10, BROKE lt I0, 0, BROKE print "Called random just fine\n" exit 0 BROKE: print "Failure: random number " print I0 print " is not in range 0..9\n" end CODE Called random just fine OUT output_is(<<'CODE', <<OUT, "generate random num"); rand N0 print "Called random just fine\n" end CODE Called random just fine OUT output_is(<<'CODE', <<OUT, "generate random 10>num>=0"); rand N0, 10.0 ge N0, 10.0, BROKE lt N0, 0, BROKE print "Called random just fine\n" exit 0 BROKE: print "Failure: random number " print N0 print " is not in range 0.0..<10.0\n" end CODE Called random just fine OUT output_is(<<'CODE', <<OUT, "Seed RNG"); srand 1 print "Seeded the rng just fine\n" end CODE Seeded the rng just fine OUT 1; # HONK