summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-random/src/random.c
diff options
context:
space:
mode:
authorMATSUMOTO Ryosuke <[email protected]>2013-03-23 18:54:56 +0900
committerMATSUMOTO Ryosuke <[email protected]>2013-03-23 18:54:56 +0900
commitab82a86da4add084624771d98961619be8e2b1e8 (patch)
tree5291cccd9c4a25570a6e1d3f0dad9ba578129a66 /mrbgems/mruby-random/src/random.c
parentacab35a2a54e00e197b7372e940b83235480179d (diff)
downloadmruby-ab82a86da4add084624771d98961619be8e2b1e8.tar.gz
mruby-ab82a86da4add084624771d98961619be8e2b1e8.zip
Add mruby-random mrbgem (no activation though)
Diffstat (limited to 'mrbgems/mruby-random/src/random.c')
-rw-r--r--mrbgems/mruby-random/src/random.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c
new file mode 100644
index 000000000..9b5858a76
--- /dev/null
+++ b/mrbgems/mruby-random/src/random.c
@@ -0,0 +1,140 @@
+/*
+** random.c - Random module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include "mruby.h"
+#include "mruby/variable.h"
+#include "mt19937ar.h"
+
+#include <time.h>
+
+#define RAND_SEED_KEY "$mrb_ext_rand_seed"
+
+void mt_srand(unsigned long seed)
+{
+ init_genrand(seed);
+}
+
+unsigned long mt_rand()
+{
+ return genrand_int32();
+}
+
+double mt_rand_real()
+{
+ return genrand_real1();
+}
+
+mrb_value mrb_random_mt_srand(mrb_state *mrb, mrb_value seed)
+{
+ if (mrb_nil_p(seed)) {
+ seed = mrb_fixnum_value(time(NULL) + mt_rand());
+ if (mrb_fixnum(seed) < 0) {
+ seed = mrb_fixnum_value( 0 - mrb_fixnum(seed));
+ }
+ }
+
+ mt_srand((unsigned) mrb_fixnum(seed));
+
+ return seed;
+}
+
+mrb_value mrb_random_mt_rand(mrb_state *mrb, mrb_value max)
+{
+ mrb_value value;
+
+ if (mrb_fixnum(max) == 0) {
+ value = mrb_float_value(mt_rand_real());
+ } else {
+ value = mrb_fixnum_value(mt_rand() % mrb_fixnum(max));
+ }
+
+ return value;
+}
+
+static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self)
+{
+ mrb_value *argv;
+ mrb_int argc;
+ mrb_value max;
+
+ mrb_get_args(mrb, "*", &argv, &argc);
+
+ if (argc == 0) {
+ max = mrb_fixnum_value(0);
+ } else if (argc == 1) {
+ max = argv[0];
+ if (!mrb_nil_p(max) && !mrb_fixnum_p(max)) {
+ max = mrb_check_convert_type(mrb, max, MRB_TT_FIXNUM, "Fixnum", "to_int");
+ }
+ if (!mrb_nil_p(max) && mrb_fixnum(max) < 0) {
+ max = mrb_fixnum_value(0 - mrb_fixnum(max));
+ }
+
+ if (!mrb_fixnum_p(max)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type");
+ return mrb_nil_value();
+ }
+ } else {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..1)", argc);
+ return mrb_nil_value();
+ }
+
+ mrb_value seed = mrb_gv_get(mrb, mrb_intern(mrb, RAND_SEED_KEY));
+ if (mrb_nil_p(seed))
+ mrb_random_mt_srand(mrb, mrb_nil_value());
+
+ return mrb_random_mt_rand(mrb, max);
+}
+
+static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self)
+{
+ mrb_int argc;
+ mrb_value *argv;
+ mrb_value seed;
+
+ mrb_get_args(mrb, "*", &argv, &argc);
+
+ if (argc == 0) {
+ seed = mrb_nil_value();
+ } else if (argc == 1) {
+ seed = argv[0];
+ if (!mrb_nil_p(seed) && !mrb_fixnum_p(seed)) {
+ seed = mrb_check_convert_type(mrb, seed, MRB_TT_FIXNUM, "Fixnum", "to_int");
+ }
+ if (!mrb_nil_p(seed) && mrb_fixnum(seed) < 0) {
+ seed = mrb_fixnum_value(0 - mrb_fixnum(seed));
+ }
+
+ if (!mrb_fixnum_p(seed)) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type");
+ return mrb_nil_value();
+ }
+ } else {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..1)", argc);
+ return mrb_nil_value();
+ }
+
+ seed = mrb_random_mt_srand(mrb, seed);
+ mrb_value old_seed = mrb_gv_get(mrb, mrb_intern(mrb, RAND_SEED_KEY));
+ mrb_gv_set(mrb, mrb_intern(mrb, RAND_SEED_KEY), seed);
+
+ return old_seed;
+}
+
+void mrb_mruby_random_gem_init(mrb_state *mrb)
+{
+ struct RClass *random;
+
+ random = mrb_define_module(mrb, "Random");
+
+ mrb_define_class_method(mrb, random, "rand", mrb_random_rand, ARGS_ANY());
+ mrb_define_class_method(mrb, random, "srand", mrb_random_srand, ARGS_ANY());
+}
+
+void mrb_mruby_random_gem_final(mrb_state *mrb)
+{
+}
+