Commit 73593f7d authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #2625 from suzukaze/add-kernel.Integer

Add kernel#Integer
parents aec12c30 28c80462
...@@ -316,6 +316,7 @@ MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name); ...@@ -316,6 +316,7 @@ MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name);
MRB_API mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value); MRB_API mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value);
MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value); MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2); MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base);
MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
......
...@@ -23,6 +23,51 @@ mrb_f_method(mrb_state *mrb, mrb_value self) ...@@ -23,6 +23,51 @@ mrb_f_method(mrb_state *mrb, mrb_value self)
return mrb_nil_value(); return mrb_nil_value();
} }
/*
* call-seq:
* Integer(arg,base=0) -> integer
*
* Converts <i>arg</i> to a <code>Fixnum</code>.
* Numeric types are converted directly (with floating point numbers
* being truncated). <i>base</i> (0, or between 2 and 36) is a base for
* integer string representation. If <i>arg</i> is a <code>String</code>,
* when <i>base</i> is omitted or equals to zero, radix indicators
* (<code>0</code>, <code>0b</code>, and <code>0x</code>) are honored.
* In any case, strings should be strictly conformed to numeric
* representation. This behavior is different from that of
* <code>String#to_i</code>. Non string values will be converted using
* <code>to_int</code>, and <code>to_i</code>. Passing <code>nil</code>
* raises a TypeError.
*
* Integer(123.999) #=> 123
* Integer("0x1a") #=> 26
* Integer(Time.new) #=> 1204973019
* Integer("0930", 10) #=> 930
* Integer("111", 2) #=> 7
* Integer(nil) #=> TypeError
*/
static mrb_value
mrb_f_integer(mrb_state *mrb, mrb_value self)
{
mrb_value *argv;
mrb_value arg;
int argc;
int base = 0;
mrb_get_args(mrb, "*", &argv, &argc);
switch (argc) {
case 2:
base = mrb_fixnum(argv[1]);
case 1:
arg = argv[0];
break;
default:
mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1..2)",
mrb_fixnum_value(argc));
}
return mrb_convert_to_integer(mrb, arg, base);
}
/* /*
* call-seq: * call-seq:
* Float(arg) -> float * Float(arg) -> float
...@@ -137,6 +182,7 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb) ...@@ -137,6 +182,7 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2)); mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2));
mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE()); mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY());
mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1)); mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
......
...@@ -17,6 +17,14 @@ assert('Kernel#__method__') do ...@@ -17,6 +17,14 @@ assert('Kernel#__method__') do
assert_equal(:m2, c.new.m2) assert_equal(:m2, c.new.m2)
end end
assert('Kernel#Integer') do
assert_equal(123, Integer(123.999))
assert_equal(26, Integer("0x1a"))
assert_equal(930, Integer("0930", 10))
assert_equal(7, Integer("111", 2))
assert_raise(TypeError) { Integer(nil) }
end
assert('Kernel#Float') do assert('Kernel#Float') do
assert_equal(1.0, Float(1)) assert_equal(1.0, Float(1))
assert_equal(123.456, Float(123.456)) assert_equal(123.456, Float(123.456))
......
...@@ -516,7 +516,7 @@ mrb_to_int(mrb_state *mrb, mrb_value val) ...@@ -516,7 +516,7 @@ mrb_to_int(mrb_state *mrb, mrb_value val)
return mrb_to_integer(mrb, val, "to_int"); return mrb_to_integer(mrb, val, "to_int");
} }
static mrb_value MRB_API mrb_value
mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
{ {
mrb_value tmp; mrb_value tmp;
...@@ -537,13 +537,17 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) ...@@ -537,13 +537,17 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
if (base != 0) goto arg_error; if (base != 0) goto arg_error;
return val; return val;
case MRB_TT_STRING:
string_conv:
return mrb_str_to_inum(mrb, val, base, TRUE);
default: default:
break; break;
} }
if (base != 0) { if (base != 0) {
tmp = mrb_check_string_type(mrb, val); tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) { if (!mrb_nil_p(tmp)) {
return mrb_str_to_inum(mrb, val, base, TRUE); goto string_conv;
} }
arg_error: arg_error:
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
......
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