summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-rational/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2019-05-17 16:37:34 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2019-05-17 16:37:34 +0900
commitb6e9fab64949b91f00d07c890935642f44147615 (patch)
tree13bfb6eb1889d82cdfb9d323b55293473cc9837c /mrbgems/mruby-rational/src
parentcec92673ae9e24d73a6feb2d69602b5fa60dcddd (diff)
downloadmruby-b6e9fab64949b91f00d07c890935642f44147615.tar.gz
mruby-b6e9fab64949b91f00d07c890935642f44147615.zip
Implement part of `Rational` in C.
Diffstat (limited to 'mrbgems/mruby-rational/src')
-rw-r--r--mrbgems/mruby-rational/src/rational.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/mrbgems/mruby-rational/src/rational.c b/mrbgems/mruby-rational/src/rational.c
new file mode 100644
index 000000000..14a9b045d
--- /dev/null
+++ b/mrbgems/mruby-rational/src/rational.c
@@ -0,0 +1,90 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/istruct.h>
+
+struct mrb_rational {
+ mrb_int numerator;
+ mrb_int denominator;
+};
+
+static struct mrb_rational*
+rational_ptr(mrb_value v)
+{
+ return (struct mrb_rational*)mrb_istruct_ptr(v);
+}
+
+static mrb_value
+rational_numerator(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ return mrb_fixnum_value(p->numerator);
+}
+
+static mrb_value
+rational_denominator(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ return mrb_fixnum_value(p->denominator);
+}
+
+static mrb_value
+rational_initialize(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ mrb_get_args(mrb, "ii", &p->numerator, &p->denominator);
+ return self;
+}
+
+static mrb_value
+rational_to_f(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ mrb_float f = (mrb_float)p->numerator / (mrb_float)p->denominator;
+
+ return mrb_float_value(mrb, f);
+}
+
+static mrb_value
+rational_to_i(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ return mrb_fixnum_value(p->numerator / p->denominator);
+}
+
+static mrb_value
+rational_to_r(mrb_state *mrb, mrb_value self)
+{
+ return self;
+}
+
+static mrb_value
+rational_negative_p(mrb_state *mrb, mrb_value self)
+{
+ struct mrb_rational *p = rational_ptr(self);
+ if (p->numerator < 0) {
+ return mrb_true_value();
+ }
+ return mrb_false_value();
+}
+
+void mrb_mruby_rational_gem_init(mrb_state *mrb)
+{
+ struct RClass *rat;
+
+ mrb_assert(sizeof(struct mrb_rational) < ISTRUCT_DATA_SIZE);
+ rat = mrb_define_class(mrb, "Rational", mrb_class_get(mrb, "Numeric"));
+ MRB_SET_INSTANCE_TT(rat, MRB_TT_ISTRUCT);
+ mrb_define_method(mrb, rat, "numerator", rational_numerator, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "denominator", rational_denominator, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "initialize", rational_initialize, MRB_ARGS_REQ(2));
+ mrb_define_method(mrb, rat, "to_f", rational_to_f, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "to_i", rational_to_i, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "to_r", rational_to_r, MRB_ARGS_NONE());
+ mrb_define_method(mrb, rat, "negative?", rational_negative_p, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_rational_gem_final(mrb_state* mrb)
+{
+}