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

Reply via email to