diff options
| author | MATSUMOTO Ryosuke <[email protected]> | 2013-03-26 21:58:12 +0900 |
|---|---|---|
| committer | MATSUMOTO Ryosuke <[email protected]> | 2013-03-26 21:58:12 +0900 |
| commit | ffa79b1aec692ddb8348d15c42587b442a42b6b6 (patch) | |
| tree | 2f76e7bd4a51fbf81a044cccac8382b1ff9fc43b /mrbgems/mruby-random/src | |
| parent | d2c946f68d1c65366aa8a62d8be25d9d98c6daa3 (diff) | |
| download | mruby-ffa79b1aec692ddb8348d15c42587b442a42b6b6.tar.gz mruby-ffa79b1aec692ddb8348d15c42587b442a42b6b6.zip | |
Add Random#rand and Random#srand
Diffstat (limited to 'mrbgems/mruby-random/src')
| -rw-r--r-- | mrbgems/mruby-random/src/random.c | 114 |
1 files changed, 112 insertions, 2 deletions
diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index defa087df..3dcf39709 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -10,7 +10,8 @@ #include <time.h> -#define GLOBAL_RAND_SEED_KEY "$mrb_g_rand_seed" +#define GLOBAL_RAND_SEED_KEY "$mrb_g_rand_seed" +#define INSTANCE_RAND_SEED_KEY "$mrb_i_rand_seed" static void mt_srand(unsigned long seed) { @@ -54,6 +55,7 @@ static mrb_value mrb_random_mt_rand(mrb_state *mrb, mrb_value max) return value; } + static mrb_value mrb_random_g_rand(mrb_state *mrb, mrb_value self) { mrb_value *argv; @@ -124,16 +126,124 @@ static mrb_value mrb_random_g_srand(mrb_state *mrb, mrb_value self) return old_seed; } +static mrb_value mrb_random_init(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_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY), seed); + + return self; +} + +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_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_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_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY)); + mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY), seed); + + return old_seed; +} + void mrb_mruby_random_gem_init(mrb_state *mrb) { struct RClass *random; mrb_define_method(mrb, mrb->kernel_module, "rand", mrb_random_g_rand, ARGS_ANY()); - mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_rand, ARGS_ANY()); + mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, ARGS_ANY()); random = mrb_define_class(mrb, "Random", mrb->object_class); mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, ARGS_ANY()); mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, ARGS_ANY()); + + mrb_define_method(mrb, random, "initialize", mrb_random_init, ARGS_ANY()); + mrb_define_method(mrb, random, "rand", mrb_random_rand, ARGS_ANY()); + mrb_define_method(mrb, random, "srand", mrb_random_srand, ARGS_ANY()); } void mrb_mruby_random_gem_final(mrb_state *mrb) |
