summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-10-29 13:17:50 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-10-29 13:17:50 +0900
commit73593f7d193d89bcc160ae388bdd5850ff26c87b (patch)
treeba4691431a3f0d63ff6d1750304fa5fd15c70df4
parentaec12c30e2258148ea8b2a866a1f39b103c7afd7 (diff)
parent28c804621a9cace9d689130930c27114f7c1da3a (diff)
downloadmruby-73593f7d193d89bcc160ae388bdd5850ff26c87b.tar.gz
mruby-73593f7d193d89bcc160ae388bdd5850ff26c87b.zip
Merge pull request #2625 from suzukaze/add-kernel.Integer
Add kernel#Integer
-rw-r--r--include/mruby.h1
-rw-r--r--mrbgems/mruby-kernel-ext/src/kernel.c46
-rw-r--r--mrbgems/mruby-kernel-ext/test/kernel.rb8
-rw-r--r--src/object.c8
4 files changed, 61 insertions, 2 deletions
diff --git a/include/mruby.h b/include/mruby.h
index 2fd0a4af7..dd7cdab08 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -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_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_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_Float(mrb_state *mrb, mrb_value val);
MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c
index 63a671aa9..a72516f48 100644
--- a/mrbgems/mruby-kernel-ext/src/kernel.c
+++ b/mrbgems/mruby-kernel-ext/src/kernel.c
@@ -25,6 +25,51 @@ mrb_f_method(mrb_state *mrb, mrb_value self)
/*
* 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:
* Float(arg) -> float
*
* Returns <i>arg</i> converted to a float. Numeric types are converted
@@ -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_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, "String", mrb_f_string, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
diff --git a/mrbgems/mruby-kernel-ext/test/kernel.rb b/mrbgems/mruby-kernel-ext/test/kernel.rb
index 3e6758b1b..c58fb465c 100644
--- a/mrbgems/mruby-kernel-ext/test/kernel.rb
+++ b/mrbgems/mruby-kernel-ext/test/kernel.rb
@@ -17,6 +17,14 @@ assert('Kernel#__method__') do
assert_equal(:m2, c.new.m2)
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_equal(1.0, Float(1))
assert_equal(123.456, Float(123.456))
diff --git a/src/object.c b/src/object.c
index 143acfaa4..c5fb74575 100644
--- a/src/object.c
+++ b/src/object.c
@@ -516,7 +516,7 @@ mrb_to_int(mrb_state *mrb, mrb_value val)
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_value tmp;
@@ -537,13 +537,17 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
if (base != 0) goto arg_error;
return val;
+ case MRB_TT_STRING:
+ string_conv:
+ return mrb_str_to_inum(mrb, val, base, TRUE);
+
default:
break;
}
if (base != 0) {
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) {
- return mrb_str_to_inum(mrb, val, base, TRUE);
+ goto string_conv;
}
arg_error:
mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");