mbed I/F binding for mruby

Dependents:   mruby_mbed_web mirb_mbed

mbed-mruby

How to use

Class

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 /*
mzta 0:158c61bb030f 2 ** object.c - Object, NilClass, TrueClass, FalseClass class
mzta 0:158c61bb030f 3 **
mzta 0:158c61bb030f 4 ** See Copyright Notice in mruby.h
mzta 0:158c61bb030f 5 */
mzta 0:158c61bb030f 6
mzta 0:158c61bb030f 7 #include "mruby.h"
mzta 0:158c61bb030f 8 #include "mruby/class.h"
mzta 0:158c61bb030f 9 #include "mruby/numeric.h"
mzta 0:158c61bb030f 10 #include "mruby/string.h"
mzta 0:158c61bb030f 11
mzta 0:158c61bb030f 12 MRB_API mrb_bool
mzta 0:158c61bb030f 13 mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
mzta 0:158c61bb030f 14 {
mzta 0:158c61bb030f 15 if (mrb_type(v1) != mrb_type(v2)) return FALSE;
mzta 0:158c61bb030f 16 switch (mrb_type(v1)) {
mzta 0:158c61bb030f 17 case MRB_TT_TRUE:
mzta 0:158c61bb030f 18 return TRUE;
mzta 0:158c61bb030f 19
mzta 0:158c61bb030f 20 case MRB_TT_FALSE:
mzta 0:158c61bb030f 21 case MRB_TT_FIXNUM:
mzta 0:158c61bb030f 22 return (mrb_fixnum(v1) == mrb_fixnum(v2));
mzta 0:158c61bb030f 23 case MRB_TT_SYMBOL:
mzta 0:158c61bb030f 24 return (mrb_symbol(v1) == mrb_symbol(v2));
mzta 0:158c61bb030f 25
mzta 0:158c61bb030f 26 case MRB_TT_FLOAT:
mzta 0:158c61bb030f 27 return (mrb_float(v1) == mrb_float(v2));
mzta 0:158c61bb030f 28
mzta 0:158c61bb030f 29 default:
mzta 0:158c61bb030f 30 return (mrb_ptr(v1) == mrb_ptr(v2));
mzta 0:158c61bb030f 31 }
mzta 0:158c61bb030f 32 }
mzta 0:158c61bb030f 33
mzta 0:158c61bb030f 34 MRB_API mrb_bool
mzta 0:158c61bb030f 35 mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2)
mzta 0:158c61bb030f 36 {
mzta 0:158c61bb030f 37 /* temporary definition */
mzta 0:158c61bb030f 38 return mrb_obj_eq(mrb, v1, v2);
mzta 0:158c61bb030f 39 }
mzta 0:158c61bb030f 40
mzta 0:158c61bb030f 41 MRB_API mrb_bool
mzta 0:158c61bb030f 42 mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
mzta 0:158c61bb030f 43 {
mzta 0:158c61bb030f 44 mrb_value result;
mzta 0:158c61bb030f 45
mzta 0:158c61bb030f 46 if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
mzta 0:158c61bb030f 47 result = mrb_funcall(mrb, obj1, "==", 1, obj2);
mzta 0:158c61bb030f 48 if (mrb_test(result)) return TRUE;
mzta 0:158c61bb030f 49 return FALSE;
mzta 0:158c61bb030f 50 }
mzta 0:158c61bb030f 51
mzta 0:158c61bb030f 52 /*
mzta 0:158c61bb030f 53 * Document-class: NilClass
mzta 0:158c61bb030f 54 *
mzta 0:158c61bb030f 55 * The class of the singleton object <code>nil</code>.
mzta 0:158c61bb030f 56 */
mzta 0:158c61bb030f 57
mzta 0:158c61bb030f 58 /* 15.2.4.3.4 */
mzta 0:158c61bb030f 59 /*
mzta 0:158c61bb030f 60 * call_seq:
mzta 0:158c61bb030f 61 * nil.nil? -> true
mzta 0:158c61bb030f 62 *
mzta 0:158c61bb030f 63 * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
mzta 0:158c61bb030f 64 */
mzta 0:158c61bb030f 65
mzta 0:158c61bb030f 66 static mrb_value
mzta 0:158c61bb030f 67 mrb_true(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 68 {
mzta 0:158c61bb030f 69 return mrb_true_value();
mzta 0:158c61bb030f 70 }
mzta 0:158c61bb030f 71
mzta 0:158c61bb030f 72 /* 15.2.4.3.5 */
mzta 0:158c61bb030f 73 /*
mzta 0:158c61bb030f 74 * call-seq:
mzta 0:158c61bb030f 75 * nil.to_s -> ""
mzta 0:158c61bb030f 76 *
mzta 0:158c61bb030f 77 * Always returns the empty string.
mzta 0:158c61bb030f 78 */
mzta 0:158c61bb030f 79
mzta 0:158c61bb030f 80 static mrb_value
mzta 0:158c61bb030f 81 nil_to_s(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 82 {
mzta 0:158c61bb030f 83 return mrb_str_new(mrb, 0, 0);
mzta 0:158c61bb030f 84 }
mzta 0:158c61bb030f 85
mzta 0:158c61bb030f 86 static mrb_value
mzta 0:158c61bb030f 87 nil_inspect(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 88 {
mzta 0:158c61bb030f 89 return mrb_str_new_lit(mrb, "nil");
mzta 0:158c61bb030f 90 }
mzta 0:158c61bb030f 91
mzta 0:158c61bb030f 92 /***********************************************************************
mzta 0:158c61bb030f 93 * Document-class: TrueClass
mzta 0:158c61bb030f 94 *
mzta 0:158c61bb030f 95 * The global value <code>true</code> is the only instance of class
mzta 0:158c61bb030f 96 * <code>TrueClass</code> and represents a logically true value in
mzta 0:158c61bb030f 97 * boolean expressions. The class provides operators allowing
mzta 0:158c61bb030f 98 * <code>true</code> to be used in logical expressions.
mzta 0:158c61bb030f 99 */
mzta 0:158c61bb030f 100
mzta 0:158c61bb030f 101 /* 15.2.5.3.1 */
mzta 0:158c61bb030f 102 /*
mzta 0:158c61bb030f 103 * call-seq:
mzta 0:158c61bb030f 104 * true & obj -> true or false
mzta 0:158c61bb030f 105 *
mzta 0:158c61bb030f 106 * And---Returns <code>false</code> if <i>obj</i> is
mzta 0:158c61bb030f 107 * <code>nil</code> or <code>false</code>, <code>true</code> otherwise.
mzta 0:158c61bb030f 108 */
mzta 0:158c61bb030f 109
mzta 0:158c61bb030f 110 static mrb_value
mzta 0:158c61bb030f 111 true_and(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 112 {
mzta 0:158c61bb030f 113 mrb_bool obj2;
mzta 0:158c61bb030f 114
mzta 0:158c61bb030f 115 mrb_get_args(mrb, "b", &obj2);
mzta 0:158c61bb030f 116
mzta 0:158c61bb030f 117 return mrb_bool_value(obj2);
mzta 0:158c61bb030f 118 }
mzta 0:158c61bb030f 119
mzta 0:158c61bb030f 120 /* 15.2.5.3.2 */
mzta 0:158c61bb030f 121 /*
mzta 0:158c61bb030f 122 * call-seq:
mzta 0:158c61bb030f 123 * true ^ obj -> !obj
mzta 0:158c61bb030f 124 *
mzta 0:158c61bb030f 125 * Exclusive Or---Returns <code>true</code> if <i>obj</i> is
mzta 0:158c61bb030f 126 * <code>nil</code> or <code>false</code>, <code>false</code>
mzta 0:158c61bb030f 127 * otherwise.
mzta 0:158c61bb030f 128 */
mzta 0:158c61bb030f 129
mzta 0:158c61bb030f 130 static mrb_value
mzta 0:158c61bb030f 131 true_xor(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 132 {
mzta 0:158c61bb030f 133 mrb_bool obj2;
mzta 0:158c61bb030f 134
mzta 0:158c61bb030f 135 mrb_get_args(mrb, "b", &obj2);
mzta 0:158c61bb030f 136 return mrb_bool_value(!obj2);
mzta 0:158c61bb030f 137 }
mzta 0:158c61bb030f 138
mzta 0:158c61bb030f 139 /* 15.2.5.3.3 */
mzta 0:158c61bb030f 140 /*
mzta 0:158c61bb030f 141 * call-seq:
mzta 0:158c61bb030f 142 * true.to_s -> "true"
mzta 0:158c61bb030f 143 *
mzta 0:158c61bb030f 144 * The string representation of <code>true</code> is "true".
mzta 0:158c61bb030f 145 */
mzta 0:158c61bb030f 146
mzta 0:158c61bb030f 147 static mrb_value
mzta 0:158c61bb030f 148 true_to_s(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 149 {
mzta 0:158c61bb030f 150 return mrb_str_new_lit(mrb, "true");
mzta 0:158c61bb030f 151 }
mzta 0:158c61bb030f 152
mzta 0:158c61bb030f 153 /* 15.2.5.3.4 */
mzta 0:158c61bb030f 154 /*
mzta 0:158c61bb030f 155 * call-seq:
mzta 0:158c61bb030f 156 * true | obj -> true
mzta 0:158c61bb030f 157 *
mzta 0:158c61bb030f 158 * Or---Returns <code>true</code>. As <i>anObject</i> is an argument to
mzta 0:158c61bb030f 159 * a method call, it is always evaluated; there is no short-circuit
mzta 0:158c61bb030f 160 * evaluation in this case.
mzta 0:158c61bb030f 161 *
mzta 0:158c61bb030f 162 * true | puts("or")
mzta 0:158c61bb030f 163 * true || puts("logical or")
mzta 0:158c61bb030f 164 *
mzta 0:158c61bb030f 165 * <em>produces:</em>
mzta 0:158c61bb030f 166 *
mzta 0:158c61bb030f 167 * or
mzta 0:158c61bb030f 168 */
mzta 0:158c61bb030f 169
mzta 0:158c61bb030f 170 static mrb_value
mzta 0:158c61bb030f 171 true_or(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 172 {
mzta 0:158c61bb030f 173 return mrb_true_value();
mzta 0:158c61bb030f 174 }
mzta 0:158c61bb030f 175
mzta 0:158c61bb030f 176 /*
mzta 0:158c61bb030f 177 * Document-class: FalseClass
mzta 0:158c61bb030f 178 *
mzta 0:158c61bb030f 179 * The global value <code>false</code> is the only instance of class
mzta 0:158c61bb030f 180 * <code>FalseClass</code> and represents a logically false value in
mzta 0:158c61bb030f 181 * boolean expressions. The class provides operators allowing
mzta 0:158c61bb030f 182 * <code>false</code> to participate correctly in logical expressions.
mzta 0:158c61bb030f 183 *
mzta 0:158c61bb030f 184 */
mzta 0:158c61bb030f 185
mzta 0:158c61bb030f 186 /* 15.2.4.3.1 */
mzta 0:158c61bb030f 187 /* 15.2.6.3.1 */
mzta 0:158c61bb030f 188 /*
mzta 0:158c61bb030f 189 * call-seq:
mzta 0:158c61bb030f 190 * false & obj -> false
mzta 0:158c61bb030f 191 * nil & obj -> false
mzta 0:158c61bb030f 192 *
mzta 0:158c61bb030f 193 * And---Returns <code>false</code>. <i>obj</i> is always
mzta 0:158c61bb030f 194 * evaluated as it is the argument to a method call---there is no
mzta 0:158c61bb030f 195 * short-circuit evaluation in this case.
mzta 0:158c61bb030f 196 */
mzta 0:158c61bb030f 197
mzta 0:158c61bb030f 198 static mrb_value
mzta 0:158c61bb030f 199 false_and(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 200 {
mzta 0:158c61bb030f 201 return mrb_false_value();
mzta 0:158c61bb030f 202 }
mzta 0:158c61bb030f 203
mzta 0:158c61bb030f 204 /* 15.2.4.3.2 */
mzta 0:158c61bb030f 205 /* 15.2.6.3.2 */
mzta 0:158c61bb030f 206 /*
mzta 0:158c61bb030f 207 * call-seq:
mzta 0:158c61bb030f 208 * false ^ obj -> true or false
mzta 0:158c61bb030f 209 * nil ^ obj -> true or false
mzta 0:158c61bb030f 210 *
mzta 0:158c61bb030f 211 * Exclusive Or---If <i>obj</i> is <code>nil</code> or
mzta 0:158c61bb030f 212 * <code>false</code>, returns <code>false</code>; otherwise, returns
mzta 0:158c61bb030f 213 * <code>true</code>.
mzta 0:158c61bb030f 214 *
mzta 0:158c61bb030f 215 */
mzta 0:158c61bb030f 216
mzta 0:158c61bb030f 217 static mrb_value
mzta 0:158c61bb030f 218 false_xor(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 219 {
mzta 0:158c61bb030f 220 mrb_bool obj2;
mzta 0:158c61bb030f 221
mzta 0:158c61bb030f 222 mrb_get_args(mrb, "b", &obj2);
mzta 0:158c61bb030f 223 return mrb_bool_value(obj2);
mzta 0:158c61bb030f 224 }
mzta 0:158c61bb030f 225
mzta 0:158c61bb030f 226 /* 15.2.4.3.3 */
mzta 0:158c61bb030f 227 /* 15.2.6.3.4 */
mzta 0:158c61bb030f 228 /*
mzta 0:158c61bb030f 229 * call-seq:
mzta 0:158c61bb030f 230 * false | obj -> true or false
mzta 0:158c61bb030f 231 * nil | obj -> true or false
mzta 0:158c61bb030f 232 *
mzta 0:158c61bb030f 233 * Or---Returns <code>false</code> if <i>obj</i> is
mzta 0:158c61bb030f 234 * <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
mzta 0:158c61bb030f 235 */
mzta 0:158c61bb030f 236
mzta 0:158c61bb030f 237 static mrb_value
mzta 0:158c61bb030f 238 false_or(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 239 {
mzta 0:158c61bb030f 240 mrb_bool obj2;
mzta 0:158c61bb030f 241
mzta 0:158c61bb030f 242 mrb_get_args(mrb, "b", &obj2);
mzta 0:158c61bb030f 243 return mrb_bool_value(obj2);
mzta 0:158c61bb030f 244 }
mzta 0:158c61bb030f 245
mzta 0:158c61bb030f 246 /* 15.2.6.3.3 */
mzta 0:158c61bb030f 247 /*
mzta 0:158c61bb030f 248 * call-seq:
mzta 0:158c61bb030f 249 * false.to_s -> "false"
mzta 0:158c61bb030f 250 *
mzta 0:158c61bb030f 251 * 'nuf said...
mzta 0:158c61bb030f 252 */
mzta 0:158c61bb030f 253
mzta 0:158c61bb030f 254 static mrb_value
mzta 0:158c61bb030f 255 false_to_s(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 256 {
mzta 0:158c61bb030f 257 return mrb_str_new_lit(mrb, "false");
mzta 0:158c61bb030f 258 }
mzta 0:158c61bb030f 259
mzta 0:158c61bb030f 260 void
mzta 0:158c61bb030f 261 mrb_init_object(mrb_state *mrb)
mzta 0:158c61bb030f 262 {
mzta 0:158c61bb030f 263 struct RClass *n;
mzta 0:158c61bb030f 264 struct RClass *t;
mzta 0:158c61bb030f 265 struct RClass *f;
mzta 0:158c61bb030f 266
mzta 0:158c61bb030f 267 n = mrb->nil_class = mrb_define_class(mrb, "NilClass", mrb->object_class);
mzta 0:158c61bb030f 268 mrb_undef_class_method(mrb, n, "new");
mzta 0:158c61bb030f 269 mrb_define_method(mrb, n, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.4.3.1 */
mzta 0:158c61bb030f 270 mrb_define_method(mrb, n, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.4.3.2 */
mzta 0:158c61bb030f 271 mrb_define_method(mrb, n, "|", false_or, MRB_ARGS_REQ(1)); /* 15.2.4.3.3 */
mzta 0:158c61bb030f 272 mrb_define_method(mrb, n, "nil?", mrb_true, MRB_ARGS_NONE()); /* 15.2.4.3.4 */
mzta 0:158c61bb030f 273 mrb_define_method(mrb, n, "to_s", nil_to_s, MRB_ARGS_NONE()); /* 15.2.4.3.5 */
mzta 0:158c61bb030f 274 mrb_define_method(mrb, n, "inspect", nil_inspect, MRB_ARGS_NONE());
mzta 0:158c61bb030f 275
mzta 0:158c61bb030f 276 t = mrb->true_class = mrb_define_class(mrb, "TrueClass", mrb->object_class);
mzta 0:158c61bb030f 277 mrb_undef_class_method(mrb, t, "new");
mzta 0:158c61bb030f 278 mrb_define_method(mrb, t, "&", true_and, MRB_ARGS_REQ(1)); /* 15.2.5.3.1 */
mzta 0:158c61bb030f 279 mrb_define_method(mrb, t, "^", true_xor, MRB_ARGS_REQ(1)); /* 15.2.5.3.2 */
mzta 0:158c61bb030f 280 mrb_define_method(mrb, t, "to_s", true_to_s, MRB_ARGS_NONE()); /* 15.2.5.3.3 */
mzta 0:158c61bb030f 281 mrb_define_method(mrb, t, "|", true_or, MRB_ARGS_REQ(1)); /* 15.2.5.3.4 */
mzta 0:158c61bb030f 282 mrb_define_method(mrb, t, "inspect", true_to_s, MRB_ARGS_NONE());
mzta 0:158c61bb030f 283
mzta 0:158c61bb030f 284 f = mrb->false_class = mrb_define_class(mrb, "FalseClass", mrb->object_class);
mzta 0:158c61bb030f 285 mrb_undef_class_method(mrb, f, "new");
mzta 0:158c61bb030f 286 mrb_define_method(mrb, f, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.6.3.1 */
mzta 0:158c61bb030f 287 mrb_define_method(mrb, f, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.6.3.2 */
mzta 0:158c61bb030f 288 mrb_define_method(mrb, f, "to_s", false_to_s, MRB_ARGS_NONE()); /* 15.2.6.3.3 */
mzta 0:158c61bb030f 289 mrb_define_method(mrb, f, "|", false_or, MRB_ARGS_REQ(1)); /* 15.2.6.3.4 */
mzta 0:158c61bb030f 290 mrb_define_method(mrb, f, "inspect", false_to_s, MRB_ARGS_NONE());
mzta 0:158c61bb030f 291 }
mzta 0:158c61bb030f 292
mzta 0:158c61bb030f 293 static mrb_value
mzta 0:158c61bb030f 294 inspect_type(mrb_state *mrb, mrb_value val)
mzta 0:158c61bb030f 295 {
mzta 0:158c61bb030f 296 if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) {
mzta 0:158c61bb030f 297 return mrb_inspect(mrb, val);
mzta 0:158c61bb030f 298 }
mzta 0:158c61bb030f 299 else {
mzta 0:158c61bb030f 300 return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val));
mzta 0:158c61bb030f 301 }
mzta 0:158c61bb030f 302 }
mzta 0:158c61bb030f 303
mzta 0:158c61bb030f 304 static mrb_value
mzta 0:158c61bb030f 305 convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise)
mzta 0:158c61bb030f 306 {
mzta 0:158c61bb030f 307 mrb_sym m = 0;
mzta 0:158c61bb030f 308
mzta 0:158c61bb030f 309 m = mrb_intern_cstr(mrb, method);
mzta 0:158c61bb030f 310 if (!mrb_respond_to(mrb, val, m)) {
mzta 0:158c61bb030f 311 if (raise) {
mzta 0:158c61bb030f 312 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname));
mzta 0:158c61bb030f 313 }
mzta 0:158c61bb030f 314 return mrb_nil_value();
mzta 0:158c61bb030f 315 }
mzta 0:158c61bb030f 316 return mrb_funcall_argv(mrb, val, m, 0, 0);
mzta 0:158c61bb030f 317 }
mzta 0:158c61bb030f 318
mzta 0:158c61bb030f 319 MRB_API mrb_value
mzta 0:158c61bb030f 320 mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
mzta 0:158c61bb030f 321 {
mzta 0:158c61bb030f 322 mrb_value v;
mzta 0:158c61bb030f 323
mzta 0:158c61bb030f 324 if (mrb_fixnum_p(val)) return val;
mzta 0:158c61bb030f 325 v = convert_type(mrb, val, "Integer", method, FALSE);
mzta 0:158c61bb030f 326 if (mrb_nil_p(v) || !mrb_fixnum_p(v)) {
mzta 0:158c61bb030f 327 return mrb_nil_value();
mzta 0:158c61bb030f 328 }
mzta 0:158c61bb030f 329 return v;
mzta 0:158c61bb030f 330 }
mzta 0:158c61bb030f 331
mzta 0:158c61bb030f 332 MRB_API mrb_value
mzta 0:158c61bb030f 333 mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
mzta 0:158c61bb030f 334 {
mzta 0:158c61bb030f 335 mrb_value v;
mzta 0:158c61bb030f 336
mzta 0:158c61bb030f 337 if (mrb_type(val) == type) return val;
mzta 0:158c61bb030f 338 v = convert_type(mrb, val, tname, method, TRUE);
mzta 0:158c61bb030f 339 if (mrb_type(v) != type) {
mzta 0:158c61bb030f 340 mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val,
mzta 0:158c61bb030f 341 mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method));
mzta 0:158c61bb030f 342 }
mzta 0:158c61bb030f 343 return v;
mzta 0:158c61bb030f 344 }
mzta 0:158c61bb030f 345
mzta 0:158c61bb030f 346 MRB_API mrb_value
mzta 0:158c61bb030f 347 mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
mzta 0:158c61bb030f 348 {
mzta 0:158c61bb030f 349 mrb_value v;
mzta 0:158c61bb030f 350
mzta 0:158c61bb030f 351 if (mrb_type(val) == type && type != MRB_TT_DATA) return val;
mzta 0:158c61bb030f 352 v = convert_type(mrb, val, tname, method, FALSE);
mzta 0:158c61bb030f 353 if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
mzta 0:158c61bb030f 354 return v;
mzta 0:158c61bb030f 355 }
mzta 0:158c61bb030f 356
mzta 0:158c61bb030f 357 static const struct types {
mzta 0:158c61bb030f 358 unsigned char type;
mzta 0:158c61bb030f 359 const char *name;
mzta 0:158c61bb030f 360 } builtin_types[] = {
mzta 0:158c61bb030f 361 /* {MRB_TT_NIL, "nil"}, */
mzta 0:158c61bb030f 362 {MRB_TT_FALSE, "false"},
mzta 0:158c61bb030f 363 {MRB_TT_TRUE, "true"},
mzta 0:158c61bb030f 364 {MRB_TT_FIXNUM, "Fixnum"},
mzta 0:158c61bb030f 365 {MRB_TT_SYMBOL, "Symbol"}, /* :symbol */
mzta 0:158c61bb030f 366 {MRB_TT_MODULE, "Module"},
mzta 0:158c61bb030f 367 {MRB_TT_OBJECT, "Object"},
mzta 0:158c61bb030f 368 {MRB_TT_CLASS, "Class"},
mzta 0:158c61bb030f 369 {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
mzta 0:158c61bb030f 370 {MRB_TT_SCLASS, "SClass"},
mzta 0:158c61bb030f 371 {MRB_TT_PROC, "Proc"},
mzta 0:158c61bb030f 372 {MRB_TT_FLOAT, "Float"},
mzta 0:158c61bb030f 373 {MRB_TT_ARRAY, "Array"},
mzta 0:158c61bb030f 374 {MRB_TT_HASH, "Hash"},
mzta 0:158c61bb030f 375 {MRB_TT_STRING, "String"},
mzta 0:158c61bb030f 376 {MRB_TT_RANGE, "Range"},
mzta 0:158c61bb030f 377 /* {MRB_TT_BIGNUM, "Bignum"}, */
mzta 0:158c61bb030f 378 {MRB_TT_FILE, "File"},
mzta 0:158c61bb030f 379 {MRB_TT_DATA, "Data"}, /* internal use: wrapped C pointers */
mzta 0:158c61bb030f 380 /* {MRB_TT_VARMAP, "Varmap"}, */ /* internal use: dynamic variables */
mzta 0:158c61bb030f 381 /* {MRB_TT_NODE, "Node"}, */ /* internal use: syntax tree node */
mzta 0:158c61bb030f 382 /* {MRB_TT_UNDEF, "undef"}, */ /* internal use: #undef; should not happen */
mzta 0:158c61bb030f 383 {-1, 0}
mzta 0:158c61bb030f 384 };
mzta 0:158c61bb030f 385
mzta 0:158c61bb030f 386 MRB_API void
mzta 0:158c61bb030f 387 mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
mzta 0:158c61bb030f 388 {
mzta 0:158c61bb030f 389 const struct types *type = builtin_types;
mzta 0:158c61bb030f 390 enum mrb_vtype xt;
mzta 0:158c61bb030f 391
mzta 0:158c61bb030f 392 xt = mrb_type(x);
mzta 0:158c61bb030f 393 if ((xt != t) || (xt == MRB_TT_DATA)) {
mzta 0:158c61bb030f 394 while (type->type < MRB_TT_MAXDEFINE) {
mzta 0:158c61bb030f 395 if (type->type == t) {
mzta 0:158c61bb030f 396 const char *etype;
mzta 0:158c61bb030f 397
mzta 0:158c61bb030f 398 if (mrb_nil_p(x)) {
mzta 0:158c61bb030f 399 etype = "nil";
mzta 0:158c61bb030f 400 }
mzta 0:158c61bb030f 401 else if (mrb_fixnum_p(x)) {
mzta 0:158c61bb030f 402 etype = "Fixnum";
mzta 0:158c61bb030f 403 }
mzta 0:158c61bb030f 404 else if (mrb_type(x) == MRB_TT_SYMBOL) {
mzta 0:158c61bb030f 405 etype = "Symbol";
mzta 0:158c61bb030f 406 }
mzta 0:158c61bb030f 407 else if (mrb_immediate_p(x)) {
mzta 0:158c61bb030f 408 etype = RSTRING_PTR(mrb_obj_as_string(mrb, x));
mzta 0:158c61bb030f 409 }
mzta 0:158c61bb030f 410 else {
mzta 0:158c61bb030f 411 etype = mrb_obj_classname(mrb, x);
mzta 0:158c61bb030f 412 }
mzta 0:158c61bb030f 413 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
mzta 0:158c61bb030f 414 mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name));
mzta 0:158c61bb030f 415 }
mzta 0:158c61bb030f 416 type++;
mzta 0:158c61bb030f 417 }
mzta 0:158c61bb030f 418 mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)",
mzta 0:158c61bb030f 419 mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x)));
mzta 0:158c61bb030f 420 }
mzta 0:158c61bb030f 421 }
mzta 0:158c61bb030f 422
mzta 0:158c61bb030f 423 /* 15.3.1.3.46 */
mzta 0:158c61bb030f 424 /*
mzta 0:158c61bb030f 425 * call-seq:
mzta 0:158c61bb030f 426 * obj.to_s => string
mzta 0:158c61bb030f 427 *
mzta 0:158c61bb030f 428 * Returns a string representing <i>obj</i>. The default
mzta 0:158c61bb030f 429 * <code>to_s</code> prints the object's class and an encoding of the
mzta 0:158c61bb030f 430 * object id. As a special case, the top-level object that is the
mzta 0:158c61bb030f 431 * initial execution context of Ruby programs returns ``main.''
mzta 0:158c61bb030f 432 */
mzta 0:158c61bb030f 433
mzta 0:158c61bb030f 434 MRB_API mrb_value
mzta 0:158c61bb030f 435 mrb_any_to_s(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 436 {
mzta 0:158c61bb030f 437 mrb_value str = mrb_str_buf_new(mrb, 20);
mzta 0:158c61bb030f 438 const char *cname = mrb_obj_classname(mrb, obj);
mzta 0:158c61bb030f 439
mzta 0:158c61bb030f 440 mrb_str_cat_lit(mrb, str, "#<");
mzta 0:158c61bb030f 441 mrb_str_cat_cstr(mrb, str, cname);
mzta 0:158c61bb030f 442 mrb_str_cat_lit(mrb, str, ":");
mzta 0:158c61bb030f 443 mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(obj)));
mzta 0:158c61bb030f 444 mrb_str_cat_lit(mrb, str, ">");
mzta 0:158c61bb030f 445
mzta 0:158c61bb030f 446 return str;
mzta 0:158c61bb030f 447 }
mzta 0:158c61bb030f 448
mzta 0:158c61bb030f 449 /*
mzta 0:158c61bb030f 450 * call-seq:
mzta 0:158c61bb030f 451 * obj.is_a?(class) => true or false
mzta 0:158c61bb030f 452 * obj.kind_of?(class) => true or false
mzta 0:158c61bb030f 453 *
mzta 0:158c61bb030f 454 * Returns <code>true</code> if <i>class</i> is the class of
mzta 0:158c61bb030f 455 * <i>obj</i>, or if <i>class</i> is one of the superclasses of
mzta 0:158c61bb030f 456 * <i>obj</i> or modules included in <i>obj</i>.
mzta 0:158c61bb030f 457 *
mzta 0:158c61bb030f 458 * module M; end
mzta 0:158c61bb030f 459 * class A
mzta 0:158c61bb030f 460 * include M
mzta 0:158c61bb030f 461 * end
mzta 0:158c61bb030f 462 * class B < A; end
mzta 0:158c61bb030f 463 * class C < B; end
mzta 0:158c61bb030f 464 * b = B.new
mzta 0:158c61bb030f 465 * b.instance_of? A #=> false
mzta 0:158c61bb030f 466 * b.instance_of? B #=> true
mzta 0:158c61bb030f 467 * b.instance_of? C #=> false
mzta 0:158c61bb030f 468 * b.instance_of? M #=> false
mzta 0:158c61bb030f 469 * b.kind_of? A #=> true
mzta 0:158c61bb030f 470 * b.kind_of? B #=> true
mzta 0:158c61bb030f 471 * b.kind_of? C #=> false
mzta 0:158c61bb030f 472 * b.kind_of? M #=> true
mzta 0:158c61bb030f 473 */
mzta 0:158c61bb030f 474
mzta 0:158c61bb030f 475 MRB_API mrb_bool
mzta 0:158c61bb030f 476 mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
mzta 0:158c61bb030f 477 {
mzta 0:158c61bb030f 478 struct RClass *cl = mrb_class(mrb, obj);
mzta 0:158c61bb030f 479
mzta 0:158c61bb030f 480 switch (c->tt) {
mzta 0:158c61bb030f 481 case MRB_TT_MODULE:
mzta 0:158c61bb030f 482 case MRB_TT_CLASS:
mzta 0:158c61bb030f 483 case MRB_TT_ICLASS:
mzta 0:158c61bb030f 484 break;
mzta 0:158c61bb030f 485
mzta 0:158c61bb030f 486 default:
mzta 0:158c61bb030f 487 mrb_raise(mrb, E_TYPE_ERROR, "class or module required");
mzta 0:158c61bb030f 488 }
mzta 0:158c61bb030f 489
mzta 0:158c61bb030f 490 while (cl) {
mzta 0:158c61bb030f 491 if (cl == c || cl->mt == c->mt)
mzta 0:158c61bb030f 492 return TRUE;
mzta 0:158c61bb030f 493 cl = cl->super;
mzta 0:158c61bb030f 494 }
mzta 0:158c61bb030f 495 return FALSE;
mzta 0:158c61bb030f 496 }
mzta 0:158c61bb030f 497
mzta 0:158c61bb030f 498 static mrb_value
mzta 0:158c61bb030f 499 mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
mzta 0:158c61bb030f 500 {
mzta 0:158c61bb030f 501 mrb_value v;
mzta 0:158c61bb030f 502
mzta 0:158c61bb030f 503 if (mrb_fixnum_p(val)) return val;
mzta 0:158c61bb030f 504 v = convert_type(mrb, val, "Integer", method, TRUE);
mzta 0:158c61bb030f 505 if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
mzta 0:158c61bb030f 506 mrb_value type = inspect_type(mrb, val);
mzta 0:158c61bb030f 507 mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
mzta 0:158c61bb030f 508 type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v));
mzta 0:158c61bb030f 509 }
mzta 0:158c61bb030f 510 return v;
mzta 0:158c61bb030f 511 }
mzta 0:158c61bb030f 512
mzta 0:158c61bb030f 513 MRB_API mrb_value
mzta 0:158c61bb030f 514 mrb_to_int(mrb_state *mrb, mrb_value val)
mzta 0:158c61bb030f 515 {
mzta 0:158c61bb030f 516 return mrb_to_integer(mrb, val, "to_int");
mzta 0:158c61bb030f 517 }
mzta 0:158c61bb030f 518
mzta 0:158c61bb030f 519 MRB_API mrb_value
mzta 0:158c61bb030f 520 mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
mzta 0:158c61bb030f 521 {
mzta 0:158c61bb030f 522 mrb_value tmp;
mzta 0:158c61bb030f 523
mzta 0:158c61bb030f 524 if (mrb_nil_p(val)) {
mzta 0:158c61bb030f 525 if (base != 0) goto arg_error;
mzta 0:158c61bb030f 526 mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
mzta 0:158c61bb030f 527 }
mzta 0:158c61bb030f 528 switch (mrb_type(val)) {
mzta 0:158c61bb030f 529 case MRB_TT_FLOAT:
mzta 0:158c61bb030f 530 if (base != 0) goto arg_error;
mzta 0:158c61bb030f 531 if (FIXABLE(mrb_float(val))) {
mzta 0:158c61bb030f 532 break;
mzta 0:158c61bb030f 533 }
mzta 0:158c61bb030f 534 return mrb_flo_to_fixnum(mrb, val);
mzta 0:158c61bb030f 535
mzta 0:158c61bb030f 536 case MRB_TT_FIXNUM:
mzta 0:158c61bb030f 537 if (base != 0) goto arg_error;
mzta 0:158c61bb030f 538 return val;
mzta 0:158c61bb030f 539
mzta 0:158c61bb030f 540 case MRB_TT_STRING:
mzta 0:158c61bb030f 541 string_conv:
mzta 0:158c61bb030f 542 return mrb_str_to_inum(mrb, val, base, TRUE);
mzta 0:158c61bb030f 543
mzta 0:158c61bb030f 544 default:
mzta 0:158c61bb030f 545 break;
mzta 0:158c61bb030f 546 }
mzta 0:158c61bb030f 547 if (base != 0) {
mzta 0:158c61bb030f 548 tmp = mrb_check_string_type(mrb, val);
mzta 0:158c61bb030f 549 if (!mrb_nil_p(tmp)) {
mzta 0:158c61bb030f 550 goto string_conv;
mzta 0:158c61bb030f 551 }
mzta 0:158c61bb030f 552 arg_error:
mzta 0:158c61bb030f 553 mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
mzta 0:158c61bb030f 554 }
mzta 0:158c61bb030f 555 tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
mzta 0:158c61bb030f 556 if (mrb_nil_p(tmp)) {
mzta 0:158c61bb030f 557 return mrb_to_integer(mrb, val, "to_i");
mzta 0:158c61bb030f 558 }
mzta 0:158c61bb030f 559 return tmp;
mzta 0:158c61bb030f 560 }
mzta 0:158c61bb030f 561
mzta 0:158c61bb030f 562 MRB_API mrb_value
mzta 0:158c61bb030f 563 mrb_Integer(mrb_state *mrb, mrb_value val)
mzta 0:158c61bb030f 564 {
mzta 0:158c61bb030f 565 return mrb_convert_to_integer(mrb, val, 0);
mzta 0:158c61bb030f 566 }
mzta 0:158c61bb030f 567
mzta 0:158c61bb030f 568 MRB_API mrb_value
mzta 0:158c61bb030f 569 mrb_Float(mrb_state *mrb, mrb_value val)
mzta 0:158c61bb030f 570 {
mzta 0:158c61bb030f 571 if (mrb_nil_p(val)) {
mzta 0:158c61bb030f 572 mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
mzta 0:158c61bb030f 573 }
mzta 0:158c61bb030f 574 switch (mrb_type(val)) {
mzta 0:158c61bb030f 575 case MRB_TT_FIXNUM:
mzta 0:158c61bb030f 576 return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val));
mzta 0:158c61bb030f 577
mzta 0:158c61bb030f 578 case MRB_TT_FLOAT:
mzta 0:158c61bb030f 579 return val;
mzta 0:158c61bb030f 580
mzta 0:158c61bb030f 581 case MRB_TT_STRING:
mzta 0:158c61bb030f 582 return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE));
mzta 0:158c61bb030f 583
mzta 0:158c61bb030f 584 default:
mzta 0:158c61bb030f 585 return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
mzta 0:158c61bb030f 586 }
mzta 0:158c61bb030f 587 }
mzta 0:158c61bb030f 588
mzta 0:158c61bb030f 589 MRB_API mrb_value
mzta 0:158c61bb030f 590 mrb_inspect(mrb_state *mrb, mrb_value obj)
mzta 0:158c61bb030f 591 {
mzta 0:158c61bb030f 592 return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0));
mzta 0:158c61bb030f 593 }
mzta 0:158c61bb030f 594
mzta 0:158c61bb030f 595 MRB_API mrb_bool
mzta 0:158c61bb030f 596 mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
mzta 0:158c61bb030f 597 {
mzta 0:158c61bb030f 598 if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
mzta 0:158c61bb030f 599 return mrb_test(mrb_funcall(mrb, obj1, "eql?", 1, obj2));
mzta 0:158c61bb030f 600 }
mzta 0:158c61bb030f 601