sabme ua / mruby-mbed

Dependents:   mruby_mbed_web mirb_mbed

Committer:
mzta
Date:
Mon Apr 13 05:20:15 2015 +0000
Revision:
1:8ccd1d494a4b
Parent:
0:158c61bb030f
- code refactoring.; - add SPI, SPISlave, I2C class to mruby-mbed (Incomplete).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mzta 0:158c61bb030f 1 #include "mruby.h"
mzta 0:158c61bb030f 2 #include "mruby/range.h"
mzta 0:158c61bb030f 3 #include <math.h>
mzta 0:158c61bb030f 4
mzta 0:158c61bb030f 5 static mrb_bool
mzta 0:158c61bb030f 6 r_le(mrb_state *mrb, mrb_value a, mrb_value b)
mzta 0:158c61bb030f 7 {
mzta 0:158c61bb030f 8 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
mzta 0:158c61bb030f 9 /* output :a < b => -1, a = b => 0, a > b => +1 */
mzta 0:158c61bb030f 10
mzta 0:158c61bb030f 11 if (mrb_fixnum_p(r)) {
mzta 0:158c61bb030f 12 mrb_int c = mrb_fixnum(r);
mzta 0:158c61bb030f 13 if (c == 0 || c == -1) return TRUE;
mzta 0:158c61bb030f 14 }
mzta 0:158c61bb030f 15
mzta 0:158c61bb030f 16 return FALSE;
mzta 0:158c61bb030f 17 }
mzta 0:158c61bb030f 18
mzta 0:158c61bb030f 19 static mrb_bool
mzta 0:158c61bb030f 20 r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
mzta 0:158c61bb030f 21 {
mzta 0:158c61bb030f 22 mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
mzta 0:158c61bb030f 23 /* output :a < b => -1, a = b => 0, a > b => +1 */
mzta 0:158c61bb030f 24
mzta 0:158c61bb030f 25 return mrb_fixnum_p(r) && mrb_fixnum(r) == -1;
mzta 0:158c61bb030f 26 }
mzta 0:158c61bb030f 27
mzta 0:158c61bb030f 28 /*
mzta 0:158c61bb030f 29 * call-seq:
mzta 0:158c61bb030f 30 * rng.cover?(obj) -> true or false
mzta 0:158c61bb030f 31 *
mzta 0:158c61bb030f 32 * Returns <code>true</code> if +obj+ is between the begin and end of
mzta 0:158c61bb030f 33 * the range.
mzta 0:158c61bb030f 34 *
mzta 0:158c61bb030f 35 * This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
mzta 0:158c61bb030f 36 * and <code>begin <= obj < end</code> when #exclude_end? is +true+.
mzta 0:158c61bb030f 37 *
mzta 0:158c61bb030f 38 * ("a".."z").cover?("c") #=> true
mzta 0:158c61bb030f 39 * ("a".."z").cover?("5") #=> false
mzta 0:158c61bb030f 40 * ("a".."z").cover?("cc") #=> true
mzta 0:158c61bb030f 41 */
mzta 0:158c61bb030f 42 static mrb_value
mzta 0:158c61bb030f 43 mrb_range_cover(mrb_state *mrb, mrb_value range)
mzta 0:158c61bb030f 44 {
mzta 0:158c61bb030f 45 mrb_value val;
mzta 0:158c61bb030f 46 struct RRange *r = mrb_range_ptr(range);
mzta 0:158c61bb030f 47 mrb_value beg, end;
mzta 0:158c61bb030f 48
mzta 0:158c61bb030f 49 mrb_get_args(mrb, "o", &val);
mzta 0:158c61bb030f 50
mzta 0:158c61bb030f 51 beg = r->edges->beg;
mzta 0:158c61bb030f 52 end = r->edges->end;
mzta 0:158c61bb030f 53
mzta 0:158c61bb030f 54 if (r_le(mrb, beg, val)) {
mzta 0:158c61bb030f 55 if (r->excl) {
mzta 0:158c61bb030f 56 if (r_lt(mrb, val, end))
mzta 0:158c61bb030f 57 return mrb_true_value();
mzta 0:158c61bb030f 58 }
mzta 0:158c61bb030f 59 else {
mzta 0:158c61bb030f 60 if (r_le(mrb, val, end))
mzta 0:158c61bb030f 61 return mrb_true_value();
mzta 0:158c61bb030f 62 }
mzta 0:158c61bb030f 63 }
mzta 0:158c61bb030f 64
mzta 0:158c61bb030f 65 return mrb_false_value();
mzta 0:158c61bb030f 66 }
mzta 0:158c61bb030f 67
mzta 0:158c61bb030f 68 /*
mzta 0:158c61bb030f 69 * call-seq:
mzta 0:158c61bb030f 70 * rng.first -> obj
mzta 0:158c61bb030f 71 * rng.first(n) -> an_array
mzta 0:158c61bb030f 72 *
mzta 0:158c61bb030f 73 * Returns the first object in the range, or an array of the first +n+
mzta 0:158c61bb030f 74 * elements.
mzta 0:158c61bb030f 75 *
mzta 0:158c61bb030f 76 * (10..20).first #=> 10
mzta 0:158c61bb030f 77 * (10..20).first(3) #=> [10, 11, 12]
mzta 0:158c61bb030f 78 */
mzta 0:158c61bb030f 79 static mrb_value
mzta 0:158c61bb030f 80 mrb_range_first(mrb_state *mrb, mrb_value range)
mzta 0:158c61bb030f 81 {
mzta 0:158c61bb030f 82 mrb_int num;
mzta 0:158c61bb030f 83 mrb_value array;
mzta 0:158c61bb030f 84 struct RRange *r = mrb_range_ptr(range);
mzta 0:158c61bb030f 85
mzta 0:158c61bb030f 86 if (mrb_get_args(mrb, "|i", &num) == 0) {
mzta 0:158c61bb030f 87 return r->edges->beg;
mzta 0:158c61bb030f 88 }
mzta 0:158c61bb030f 89
mzta 0:158c61bb030f 90 array = mrb_funcall(mrb, range, "to_a", 0);
mzta 0:158c61bb030f 91 return mrb_funcall(mrb, array, "first", 1, mrb_fixnum_value(num));
mzta 0:158c61bb030f 92 }
mzta 0:158c61bb030f 93
mzta 0:158c61bb030f 94 /*
mzta 0:158c61bb030f 95 * call-seq:
mzta 0:158c61bb030f 96 * rng.last -> obj
mzta 0:158c61bb030f 97 * rng.last(n) -> an_array
mzta 0:158c61bb030f 98 *
mzta 0:158c61bb030f 99 * Returns the last object in the range,
mzta 0:158c61bb030f 100 * or an array of the last +n+ elements.
mzta 0:158c61bb030f 101 *
mzta 0:158c61bb030f 102 * Note that with no arguments +last+ will return the object that defines
mzta 0:158c61bb030f 103 * the end of the range even if #exclude_end? is +true+.
mzta 0:158c61bb030f 104 *
mzta 0:158c61bb030f 105 * (10..20).last #=> 20
mzta 0:158c61bb030f 106 * (10...20).last #=> 20
mzta 0:158c61bb030f 107 * (10..20).last(3) #=> [18, 19, 20]
mzta 0:158c61bb030f 108 * (10...20).last(3) #=> [17, 18, 19]
mzta 0:158c61bb030f 109 */
mzta 0:158c61bb030f 110 static mrb_value
mzta 0:158c61bb030f 111 mrb_range_last(mrb_state *mrb, mrb_value range)
mzta 0:158c61bb030f 112 {
mzta 0:158c61bb030f 113 mrb_value num;
mzta 0:158c61bb030f 114 mrb_value array;
mzta 0:158c61bb030f 115 struct RRange *r = mrb_range_ptr(range);
mzta 0:158c61bb030f 116
mzta 0:158c61bb030f 117 if (mrb_get_args(mrb, "|o", &num) == 0) {
mzta 0:158c61bb030f 118 return r->edges->end;
mzta 0:158c61bb030f 119 }
mzta 0:158c61bb030f 120
mzta 0:158c61bb030f 121 array = mrb_funcall(mrb, range, "to_a", 0);
mzta 0:158c61bb030f 122 return mrb_funcall(mrb, array, "last", 1, mrb_to_int(mrb, num));
mzta 0:158c61bb030f 123 }
mzta 0:158c61bb030f 124
mzta 0:158c61bb030f 125 /*
mzta 0:158c61bb030f 126 * call-seq:
mzta 0:158c61bb030f 127 * rng.size -> num
mzta 0:158c61bb030f 128 *
mzta 0:158c61bb030f 129 * Returns the number of elements in the range. Both the begin and the end of
mzta 0:158c61bb030f 130 * the Range must be Numeric, otherwise nil is returned.
mzta 0:158c61bb030f 131 *
mzta 0:158c61bb030f 132 * (10..20).size #=> 11
mzta 0:158c61bb030f 133 * ('a'..'z').size #=> nil
mzta 0:158c61bb030f 134 */
mzta 0:158c61bb030f 135
mzta 0:158c61bb030f 136 static mrb_value
mzta 0:158c61bb030f 137 mrb_range_size(mrb_state *mrb, mrb_value range)
mzta 0:158c61bb030f 138 {
mzta 0:158c61bb030f 139 struct RRange *r = mrb_range_ptr(range);
mzta 0:158c61bb030f 140 mrb_value beg, end;
mzta 0:158c61bb030f 141 double beg_f, end_f;
mzta 0:158c61bb030f 142 mrb_bool num_p = TRUE;
mzta 0:158c61bb030f 143
mzta 0:158c61bb030f 144 beg = r->edges->beg;
mzta 0:158c61bb030f 145 end = r->edges->end;
mzta 0:158c61bb030f 146 if (mrb_fixnum_p(beg)) {
mzta 0:158c61bb030f 147 beg_f = (double)mrb_fixnum(beg);
mzta 0:158c61bb030f 148 }
mzta 0:158c61bb030f 149 else if (mrb_float_p(beg)) {
mzta 0:158c61bb030f 150 beg_f = mrb_float(beg);
mzta 0:158c61bb030f 151 }
mzta 0:158c61bb030f 152 else {
mzta 0:158c61bb030f 153 num_p = FALSE;
mzta 0:158c61bb030f 154 }
mzta 0:158c61bb030f 155 if (mrb_fixnum_p(end)) {
mzta 0:158c61bb030f 156 end_f = (double)mrb_fixnum(end);
mzta 0:158c61bb030f 157 }
mzta 0:158c61bb030f 158 else if (mrb_float_p(end)) {
mzta 0:158c61bb030f 159 end_f = mrb_float(end);
mzta 0:158c61bb030f 160 }
mzta 0:158c61bb030f 161 else {
mzta 0:158c61bb030f 162 num_p = FALSE;
mzta 0:158c61bb030f 163 }
mzta 0:158c61bb030f 164 if (num_p) {
mzta 0:158c61bb030f 165 double f;
mzta 0:158c61bb030f 166
mzta 0:158c61bb030f 167 if (beg_f > end_f) return mrb_fixnum_value(0);
mzta 0:158c61bb030f 168 f = end_f - beg_f;
mzta 0:158c61bb030f 169 if (!r->excl) {
mzta 0:158c61bb030f 170 return mrb_fixnum_value((mrb_int)ceil(f + 1));
mzta 0:158c61bb030f 171 }
mzta 0:158c61bb030f 172 return mrb_fixnum_value((mrb_int)ceil(f));
mzta 0:158c61bb030f 173 }
mzta 0:158c61bb030f 174 return mrb_nil_value();
mzta 0:158c61bb030f 175 }
mzta 0:158c61bb030f 176
mzta 0:158c61bb030f 177 void
mzta 0:158c61bb030f 178 mrb_mruby_range_ext_gem_init(mrb_state* mrb)
mzta 0:158c61bb030f 179 {
mzta 0:158c61bb030f 180 struct RClass * s = mrb_class_get(mrb, "Range");
mzta 0:158c61bb030f 181
mzta 0:158c61bb030f 182 mrb_define_method(mrb, s, "cover?", mrb_range_cover, MRB_ARGS_REQ(1));
mzta 0:158c61bb030f 183 mrb_define_method(mrb, s, "first", mrb_range_first, MRB_ARGS_OPT(1));
mzta 0:158c61bb030f 184 mrb_define_method(mrb, s, "last", mrb_range_last, MRB_ARGS_OPT(1));
mzta 0:158c61bb030f 185 mrb_define_method(mrb, s, "size", mrb_range_size, MRB_ARGS_NONE());
mzta 0:158c61bb030f 186 }
mzta 0:158c61bb030f 187
mzta 0:158c61bb030f 188 void
mzta 0:158c61bb030f 189 mrb_mruby_range_ext_gem_final(mrb_state* mrb)
mzta 0:158c61bb030f 190 {
mzta 0:158c61bb030f 191 }
mzta 0:158c61bb030f 192