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