Commit ddf95045 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1721 from take-cheeze/d_format_spec

add 'd' format specifier in mrb_get_args and mruby-random gem improvement
parents 2f9cf26a f863025b
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
** See Copyright Notice in mruby.h ** See Copyright Notice in mruby.h
*/ */
#include "mruby.h"
#include "mt19937ar.h" #include "mt19937ar.h"
/* Period parameters */ /* Period parameters */
......
...@@ -13,6 +13,9 @@ typedef struct { ...@@ -13,6 +13,9 @@ typedef struct {
unsigned long gen_int; unsigned long gen_int;
double gen_dbl; double gen_dbl;
}; };
mrb_int seed;
mrb_bool has_seed;
} mt_state; } mt_state;
void mrb_random_init_genrand(mt_state *, unsigned long); void mrb_random_init_genrand(mt_state *, unsigned long);
......
...@@ -13,13 +13,8 @@ ...@@ -13,13 +13,8 @@
#include <time.h> #include <time.h>
#define GLOBAL_RAND_SEED_KEY "$mrb_g_rand_seed" static char const GLOBAL_RAND_SEED_KEY[] = "$mrb_g_rand_seed";
#define GLOBAL_RAND_SEED_KEY_CSTR_LEN 16 static char const MT_STATE_KEY[] = "$mrb_i_mt_state";
#define INSTANCE_RAND_SEED_KEY "$mrb_i_rand_seed"
#define INSTANCE_RAND_SEED_KEY_CSTR_LEN 16
#define MT_STATE_KEY "$mrb_i_mt_state"
static const struct mrb_data_type mt_state_type = { static const struct mrb_data_type mt_state_type = {
MT_STATE_KEY, mrb_free, MT_STATE_KEY, mrb_free,
...@@ -143,7 +138,7 @@ mrb_random_g_rand_seed(mrb_state *mrb) ...@@ -143,7 +138,7 @@ mrb_random_g_rand_seed(mrb_state *mrb)
{ {
mrb_value seed; mrb_value seed;
seed = mrb_gv_get(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN)); seed = mrb_gv_get(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY));
if (mrb_nil_p(seed)) { if (mrb_nil_p(seed)) {
mrb_random_mt_g_srand(mrb, mrb_nil_value()); mrb_random_mt_g_srand(mrb, mrb_nil_value());
} }
...@@ -167,8 +162,8 @@ mrb_random_g_srand(mrb_state *mrb, mrb_value self) ...@@ -167,8 +162,8 @@ mrb_random_g_srand(mrb_state *mrb, mrb_value self)
seed = get_opt(mrb); seed = get_opt(mrb);
seed = mrb_random_mt_g_srand(mrb, seed); seed = mrb_random_mt_g_srand(mrb, seed);
old_seed = mrb_gv_get(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN)); old_seed = mrb_gv_get(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY));
mrb_gv_set(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN), seed); mrb_gv_set(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY), seed);
return old_seed; return old_seed;
} }
...@@ -192,7 +187,14 @@ mrb_random_init(mrb_state *mrb, mrb_value self) ...@@ -192,7 +187,14 @@ mrb_random_init(mrb_state *mrb, mrb_value self)
seed = get_opt(mrb); seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed); seed = mrb_random_mt_srand(mrb, t, seed);
mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed); if (mrb_nil_p(seed)) {
t->has_seed = FALSE;
}
else {
mrb_assert(mrb_fixnum_p(seed));
t->has_seed = TRUE;
t->seed = mrb_fixnum(seed);
}
DATA_PTR(self) = t; DATA_PTR(self) = t;
...@@ -200,13 +202,9 @@ mrb_random_init(mrb_state *mrb, mrb_value self) ...@@ -200,13 +202,9 @@ mrb_random_init(mrb_state *mrb, mrb_value self)
} }
static void static void
mrb_random_rand_seed(mrb_state *mrb, mrb_value self) mrb_random_rand_seed(mrb_state *mrb, mt_state *t)
{ {
mrb_value seed; if (!t->has_seed) {
mt_state *t = DATA_PTR(self);
seed = mrb_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN));
if (mrb_nil_p(seed)) {
mrb_random_mt_srand(mrb, t, mrb_nil_value()); mrb_random_mt_srand(mrb, t, mrb_nil_value());
} }
} }
...@@ -218,7 +216,7 @@ mrb_random_rand(mrb_state *mrb, mrb_value self) ...@@ -218,7 +216,7 @@ mrb_random_rand(mrb_state *mrb, mrb_value self)
mt_state *t = DATA_PTR(self); mt_state *t = DATA_PTR(self);
max = get_opt(mrb); max = get_opt(mrb);
mrb_random_rand_seed(mrb, self); mrb_random_rand_seed(mrb, t);
return mrb_random_mt_rand(mrb, t, max); return mrb_random_mt_rand(mrb, t, max);
} }
...@@ -231,8 +229,15 @@ mrb_random_srand(mrb_state *mrb, mrb_value self) ...@@ -231,8 +229,15 @@ mrb_random_srand(mrb_state *mrb, mrb_value self)
seed = get_opt(mrb); seed = get_opt(mrb);
seed = mrb_random_mt_srand(mrb, t, seed); seed = mrb_random_mt_srand(mrb, t, seed);
old_seed = mrb_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN)); old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value();
mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed); if (mrb_nil_p(seed)) {
t->has_seed = FALSE;
}
else {
mrb_assert(mrb_fixnum_p(seed));
t->has_seed = TRUE;
t->seed = mrb_fixnum(seed);
}
return old_seed; return old_seed;
} }
...@@ -248,17 +253,16 @@ static mrb_value ...@@ -248,17 +253,16 @@ static mrb_value
mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
{ {
mrb_int i; mrb_int i;
mrb_value random = mrb_nil_value(); mt_state *random = NULL;
if (RARRAY_LEN(ary) > 1) { if (RARRAY_LEN(ary) > 1) {
mrb_get_args(mrb, "|o", &random); mrb_get_args(mrb, "|d", &random, &mt_state_type);
if (mrb_nil_p(random)) { if (random) {
mrb_random_g_rand_seed(mrb); mrb_random_rand_seed(mrb, random);
} }
else { else {
mrb_data_check_type(mrb, random, &mt_state_type); mrb_random_g_rand_seed(mrb);
mrb_random_rand_seed(mrb, random);
} }
mrb_ary_modify(mrb, mrb_ary_ptr(ary)); mrb_ary_modify(mrb, mrb_ary_ptr(ary));
...@@ -267,11 +271,11 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) ...@@ -267,11 +271,11 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
mrb_int j; mrb_int j;
mrb_value tmp; mrb_value tmp;
if (mrb_nil_p(random)) { if (random) {
j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary)))); j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary))));
} }
else { else {
j = mrb_fixnum(mrb_random_mt_rand(mrb, DATA_PTR(random), mrb_fixnum_value(RARRAY_LEN(ary)))); j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary))));
} }
tmp = RARRAY_PTR(ary)[i]; tmp = RARRAY_PTR(ary)[i];
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "mruby/string.h" #include "mruby/string.h"
#include "mruby/variable.h" #include "mruby/variable.h"
#include "mruby/error.h" #include "mruby/error.h"
#include "mruby/data.h"
KHASH_DEFINE(mt, mrb_sym, struct RProc*, 1, kh_int_hash_func, kh_int_hash_equal) KHASH_DEFINE(mt, mrb_sym, struct RProc*, 1, kh_int_hash_func, kh_int_hash_equal)
...@@ -406,6 +407,7 @@ to_hash(mrb_state *mrb, mrb_value val) ...@@ -406,6 +407,7 @@ to_hash(mrb_state *mrb, mrb_value val)
i: Integer [mrb_int] i: Integer [mrb_int]
b: Boolean [mrb_bool] b: Boolean [mrb_bool]
n: Symbol [mrb_sym] n: Symbol [mrb_sym]
d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
&: Block [mrb_value] &: Block [mrb_value]
*: rest argument [mrb_value*,int] Receive the rest of the arguments as an array. *: rest argument [mrb_value*,int] Receive the rest of the arguments as an array.
|: optional Next argument of '|' and later are optional. |: optional Next argument of '|' and later are optional.
...@@ -658,6 +660,19 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -658,6 +660,19 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
} }
} }
break; break;
case 'd':
{
void** datap;
struct mrb_data_type const* type;
datap = va_arg(ap, void**);
type = va_arg(ap, struct mrb_data_type const*);
if (i < argc) {
*datap = mrb_data_get_ptr(mrb, *sp++, type);
++i;
}
}
break;
case '&': case '&':
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment