Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: mruby_mbed_web mirb_mbed
mrbgems/mruby-range-ext/range.c@1:8ccd1d494a4b, 2015-04-13 (annotated)
- 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?
User | Revision | Line number | New 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 |