diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-05-21 16:11:25 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2019-05-21 21:08:26 +0900 |
| commit | fccec8964a1b30cef8ff9d97e0e01f3a348e318b (patch) | |
| tree | 5ab7345ece768da33547e360be58c4bfd6859c81 /mrbgems/mruby-complex/src/complex.c | |
| parent | e941cf06a3e0351107d36d49d540562fdf49f9b4 (diff) | |
| download | mruby-fccec8964a1b30cef8ff9d97e0e01f3a348e318b.tar.gz mruby-fccec8964a1b30cef8ff9d97e0e01f3a348e318b.zip | |
Implements part of `Complex` class in C.
Diffstat (limited to 'mrbgems/mruby-complex/src/complex.c')
| -rw-r--r-- | mrbgems/mruby-complex/src/complex.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/mrbgems/mruby-complex/src/complex.c b/mrbgems/mruby-complex/src/complex.c new file mode 100644 index 000000000..5de0ae9a4 --- /dev/null +++ b/mrbgems/mruby-complex/src/complex.c @@ -0,0 +1,116 @@ +#include <mruby.h> +#include <mruby/class.h> +#include <mruby/numeric.h> + +struct mrb_complex { + mrb_float real; + mrb_float imaginary; +}; + +#include <mruby/data.h> + +static const struct mrb_data_type mrb_complex_type = {"Complex", mrb_free}; + +static mrb_value +complex_new(mrb_state *mrb, mrb_float real, mrb_float imaginary) +{ + struct RClass *c = mrb_class_get(mrb, "Complex"); + struct mrb_complex *p; + + p = (struct mrb_complex*)mrb_malloc(mrb, sizeof(struct mrb_complex)); + p->real = real; + p->imaginary = imaginary; + + return mrb_obj_value(Data_Wrap_Struct(mrb, c, &mrb_complex_type, p)); +} + +static struct mrb_complex* +complex_ptr(mrb_state *mrb, mrb_value v) +{ + struct mrb_complex *p; + + p = DATA_GET_PTR(mrb, v, &mrb_complex_type, struct mrb_complex); + if (!p) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized complex"); + } + return p; +} + +static mrb_value +complex_real(mrb_state *mrb, mrb_value self) +{ + struct mrb_complex *p = complex_ptr(mrb, self); + return mrb_float_value(mrb, p->real); +} + +static mrb_value +complex_imaginary(mrb_state *mrb, mrb_value self) +{ + struct mrb_complex *p = complex_ptr(mrb, self); + return mrb_float_value(mrb, p->imaginary); +} + +static mrb_value +complex_s_new(mrb_state *mrb, mrb_value self) +{ + mrb_float real, imaginary; + + mrb_get_args(mrb, "ff", &real, &imaginary); + return complex_new(mrb, real, imaginary); +} + +#ifndef MRB_WITHOUT_FLOAT +static mrb_value +complex_to_f(mrb_state *mrb, mrb_value self) +{ + struct mrb_complex *p = complex_ptr(mrb, self); + + if (p->imaginary != 0) { + mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self); + } + + return mrb_float_value(mrb, p->real); +} +#endif + +static mrb_value +complex_to_i(mrb_state *mrb, mrb_value self) +{ + struct mrb_complex *p = complex_ptr(mrb, self); + + if (p->imaginary != 0) { + mrb_raisef(mrb, E_RANGE_ERROR, "can't convert %S into Float", self); + } + return mrb_int_value(mrb, p->real); +} + +static mrb_value +complex_to_c(mrb_state *mrb, mrb_value self) +{ + return self; +} + +void mrb_mruby_complex_gem_init(mrb_state *mrb) +{ + struct RClass *comp; + +#ifdef COMPLEX_USE_ISTRUCT + mrb_assert(sizeof(struct mrb_complex) < ISTRUCT_DATA_SIZE); +#endif + comp = mrb_define_class(mrb, "Complex", mrb_class_get(mrb, "Numeric")); + //MRB_SET_INSTANCE_TT(comp, MRB_TT_ISTRUCT); + mrb_undef_class_method(mrb, comp, "new"); + mrb_define_class_method(mrb, comp, "_new", complex_s_new, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, comp, "real", complex_real, MRB_ARGS_NONE()); + mrb_define_method(mrb, comp, "imaginary", complex_imaginary, MRB_ARGS_NONE()); +#ifndef MRB_WITHOUT_FLOAT + mrb_define_method(mrb, comp, "to_f", complex_to_f, MRB_ARGS_NONE()); +#endif + mrb_define_method(mrb, comp, "to_i", complex_to_i, MRB_ARGS_NONE()); + mrb_define_method(mrb, comp, "to_c", complex_to_c, MRB_ARGS_NONE()); +} + +void +mrb_mruby_complex_gem_final(mrb_state* mrb) +{ +} |
