mruby/c VM Source Code release 3.4
Loading...
Searching...
No Matches
value.c
Go to the documentation of this file.
1
13
14/***** Feature test switches ************************************************/
15/***** System headers *******************************************************/
16//@cond
17#include "vm_config.h"
18#include <string.h>
19#include <assert.h>
20//@endcond
21
22/***** Local headers ********************************************************/
23#include "mrubyc.h"
24
25/***** Constant values ******************************************************/
26/***** Macros ***************************************************************/
27/***** Typedefs *************************************************************/
28/***** Function prototypes **************************************************/
29/***** Local variables ******************************************************/
30/***** Global variables *****************************************************/
31//================================================================
37void (* const mrbc_delfunc[])(mrbc_value *) = {
38 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 mrbc_instance_delete, // MRBC_TT_OBJECT = 9,
40 mrbc_proc_delete, // MRBC_TT_PROC = 10,
41 mrbc_array_delete, // MRBC_TT_ARRAY = 11,
42#if MRBC_USE_STRING
43 mrbc_string_delete, // MRBC_TT_STRING = 12,
44#else
45 NULL,
46#endif
47 mrbc_range_delete, // MRBC_TT_RANGE = 13,
48 mrbc_hash_delete, // MRBC_TT_HASH = 14,
49 mrbc_exception_delete, // MRBC_TT_EXCEPTION = 15,
50};
51
52
53/***** Signal catching functions ********************************************/
54/***** Local functions ******************************************************/
55/***** Global functions *****************************************************/
56
57//================================================================
66int mrbc_compare(const mrbc_value *v1, const mrbc_value *v2)
67{
68#if MRBC_USE_FLOAT
69 mrbc_float_t d1, d2;
70#endif
71
72 // if TT_XXX is different
73 if( mrbc_type(*v1) != mrbc_type(*v2) ) {
74#if MRBC_USE_FLOAT
75 // but Numeric?
76 if( mrbc_type(*v1) == MRBC_TT_INTEGER && mrbc_type(*v2) == MRBC_TT_FLOAT ) {
77 d1 = v1->i;
78 d2 = v2->d;
79 goto CMP_FLOAT;
80 }
81 if( mrbc_type(*v1) == MRBC_TT_FLOAT && mrbc_type(*v2) == MRBC_TT_INTEGER ) {
82 d1 = v1->d;
83 d2 = v2->i;
84 goto CMP_FLOAT;
85 }
86#endif
87
88 // leak Empty?
89 if((mrbc_type(*v1) == MRBC_TT_EMPTY && mrbc_type(*v2) == MRBC_TT_NIL) ||
90 (mrbc_type(*v1) == MRBC_TT_NIL && mrbc_type(*v2) == MRBC_TT_EMPTY)) return 0;
91
92 // other case
93 return mrbc_type(*v1) - mrbc_type(*v2);
94 }
95
96 // check value
97 switch( mrbc_type(*v1) ) {
98 case MRBC_TT_NIL:
99 case MRBC_TT_FALSE:
100 case MRBC_TT_TRUE:
101 return 0;
102
103 case MRBC_TT_INTEGER:
104 return mrbc_integer(*v1) - mrbc_integer(*v2);
105
106 case MRBC_TT_SYMBOL: {
107 const char *str1 = mrbc_symid_to_str(mrbc_symbol(*v1));
108 const char *str2 = mrbc_symid_to_str(mrbc_symbol(*v2));
109 int diff = strlen(str1) - strlen(str2);
110 int len = diff < 0 ? strlen(str1) : strlen(str2);
111 int res = memcmp(str1, str2, len);
112 return (res != 0) ? res : diff;
113 }
114
115#if MRBC_USE_FLOAT
116 case MRBC_TT_FLOAT:
117 d1 = mrbc_float(*v1);
118 d2 = mrbc_float(*v2);
119 goto CMP_FLOAT;
120#endif
121
122 case MRBC_TT_CLASS:
123 case MRBC_TT_MODULE:
124 case MRBC_TT_OBJECT:
125 case MRBC_TT_PROC:
126 return (v1->cls > v2->cls) * 2 - (v1->cls != v2->cls);
127
128 case MRBC_TT_ARRAY:
129 return mrbc_array_compare( v1, v2 );
130
131#if MRBC_USE_STRING
132 case MRBC_TT_STRING:
133 return mrbc_string_compare( v1, v2 );
134#endif
135
136 case MRBC_TT_RANGE:
137 return mrbc_range_compare( v1, v2 );
138
139 case MRBC_TT_HASH:
140 return mrbc_hash_compare( v1, v2 );
141
142 default:
143 return 1;
144 }
145
146#if MRBC_USE_FLOAT
147 CMP_FLOAT:
148 return -1 + (d1 == d2) + (d1 > d2)*2; // caution: NaN == NaN is false
149#endif
150}
151
152
153#if defined(MRBC_ALLOC_VMID)
154//================================================================
159void mrbc_clear_vm_id(mrbc_value *v)
160{
161 switch( mrbc_type(*v) ) {
162 case MRBC_TT_OBJECT: mrbc_instance_clear_vm_id(v); break;
163 case MRBC_TT_PROC: mrbc_proc_clear_vm_id(v); break;
164 case MRBC_TT_ARRAY: mrbc_array_clear_vm_id(v); break;
165#if MRBC_USE_STRING
166 case MRBC_TT_STRING: mrbc_string_clear_vm_id(v); break;
167#endif
168 case MRBC_TT_RANGE: mrbc_range_clear_vm_id(v); break;
169 case MRBC_TT_HASH: mrbc_hash_clear_vm_id(v); break;
170
171 default:
172 // Nothing
173 break;
174 }
175}
176#endif
177
178
179//================================================================
186mrbc_int_t mrbc_atoi( const char *s, int base )
187{
188 int ret = 0;
189 int sign = 0;
190
191 REDO:
192 switch( *s ) {
193 case '-':
194 sign = 1;
195 // fall through.
196 case '+':
197 s++;
198 break;
199
200 case ' ':
201 s++;
202 goto REDO;
203 }
204
205 int ch;
206 while( (ch = *s++) != '\0' ) {
207 int n;
208
209 if( 'a' <= ch ) {
210 n = ch - 'a' + 10;
211 } else
212 if( 'A' <= ch ) {
213 n = ch - 'A' + 10;
214 } else
215 if( '0' <= ch && ch <= '9' ) {
216 n = ch - '0';
217 } else {
218 break;
219 }
220 if( n >= base ) break;
221
222 ret = ret * base + n;
223 }
224
225 if( sign ) ret = -ret;
226
227 return ret;
228}
229
230
231//================================================================
239int mrbc_strcpy( char *dest, int destsize, const char *src )
240{
241 int n = destsize;
242 if( n <= 0 ) return 0;
243
244 while( --n != 0 ) {
245 if( (*dest++ = *src++) == 0 ) goto RETURN;
246 }
247 *dest = 0;
248
249 RETURN:
250 return destsize - n - 1;
251}
252
253
254//================================================================
264mrbc_int_t mrbc_val_i(struct VM *vm, const mrbc_value *val)
265{
266 if( val == NULL ) return 0;
267
268 switch(val->tt) {
269 case MRBC_TT_INTEGER:
270 return val->i;
271
272 case MRBC_TT_FLOAT:
273 return val->d;
274
275 default:
276 ;
277 }
278
279 mrbc_raise(vm, MRBC_CLASS(TypeError), "argument must be Integer or Float");
280 return 0;
281}
282
283
284//================================================================
295mrbc_int_t mrbc_val_i2(struct VM *vm, const mrbc_value *val, mrbc_int_t default_value )
296{
297 if( val == NULL || val->tt == MRBC_TT_EMPTY ) return default_value;
298
299 return mrbc_val_i( vm, val );
300}
301
302
303//================================================================
313double mrbc_val_f(struct VM *vm, const mrbc_value *val)
314{
315 if( val == NULL ) return 0;
316
317 switch(val->tt) {
318 case MRBC_TT_INTEGER:
319 return val->i;
320
321 case MRBC_TT_FLOAT:
322 return val->d;
323
324 default:
325 ;
326 }
327
328 mrbc_raise(vm, MRBC_CLASS(TypeError), "argument must be Integer or Float");
329 return 0;
330}
331
332
333//================================================================
344double mrbc_val_f2(struct VM *vm, const mrbc_value *val, double default_value )
345{
346 if( val == NULL || val->tt == MRBC_TT_EMPTY ) return default_value;
347
348 return mrbc_val_f( vm, val );
349}
350
351
352//================================================================
362const char * mrbc_val_s(struct VM *vm, const mrbc_value *val)
363{
364 if( val == NULL ) return 0;
365
366 switch(val->tt) {
367 case MRBC_TT_STRING:
368 return mrbc_string_cstr( val );
369
370 default:
371 ;
372 }
373
374 mrbc_raise(vm, MRBC_CLASS(TypeError), "argument must be String");
375 return 0;
376}
377
378
379//================================================================
390const char * mrbc_val_s2(struct VM *vm, const mrbc_value *val, const char * default_value )
391{
392 if( val == NULL || val->tt == MRBC_TT_EMPTY ) return default_value;
393
394 return mrbc_val_s( vm, val );
395}
396
397
398//================================================================
410mrbc_int_t mrbc_to_i(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
411{
412 if( val == NULL ) return 0;
413
414 switch(val->tt) {
415 case MRBC_TT_EMPTY:
416 mrbc_raise(vm, MRBC_CLASS(TypeError), 0);
417 return 0;
418
419 case MRBC_TT_INTEGER:
420 break;
421
422 case MRBC_TT_FLOAT:
423 mrbc_set_integer(val, val->d);
424 break;
425
426 default:{
427 mrbc_value ret = mrbc_send( vm, v, argc, val, "to_i", 0 );
428 if( mrbc_israised(vm) ) return 0;
429
430 mrbc_decref( val );
431 *val = ret;
432 } break;
433 }
434
435 return val->i;
436}
437
438
439//================================================================
451mrbc_float_t mrbc_to_f(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
452{
453 if( val == NULL ) return 0;
454
455 switch(val->tt) {
456 case MRBC_TT_EMPTY:
457 mrbc_raise(vm, MRBC_CLASS(TypeError), 0);
458 return 0;
459
460 case MRBC_TT_INTEGER:
461 mrbc_set_float(val, val->i);
462 break;
463
464 case MRBC_TT_FLOAT:
465 break;
466
467 default:{
468 mrbc_value ret = mrbc_send( vm, v, argc, val, "to_f", 0 );
469 if( mrbc_israised(vm) ) return 0;
470
471 mrbc_decref( val );
472 *val = ret;
473 } break;
474 }
475
476 return val->d;
477}
478
479
480//================================================================
492char * mrbc_to_s(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
493{
494 if( val == NULL ) return 0;
495
496 switch(val->tt) {
497 case MRBC_TT_EMPTY:
498 mrbc_raise(vm, MRBC_CLASS(TypeError), 0);
499 return 0;
500
501 case MRBC_TT_STRING:
502 goto RETURN;
503
504 default:{
505 mrbc_value ret = mrbc_send( vm, v, argc, val, "to_s", 0 );
506 if( mrbc_israised(vm) ) return 0;
507
508 mrbc_decref( val );
509 *val = ret;
510 } break;
511 }
512
513 RETURN:
514 return mrbc_string_cstr( val );
515}
516
517
518//================================================================
530mrbc_value * mrbc_arg(struct VM *vm, mrbc_value v[], int argc, int n)
531{
532 if( argc < n ) {
533 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
534 "wrong number of arguments (given %d, expected %d)", argc, n);
535 return 0;
536 }
537
538 return &v[n];
539}
540
541
542//================================================================
554mrbc_int_t mrbc_arg_i(struct VM *vm, mrbc_value v[], int argc, int n)
555{
556 if( argc < n ) {
557 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
558 "wrong number of arguments (given %d, expected %d)", argc, n);
559 return 0;
560 }
561
562 switch(v[n].tt) {
563 case MRBC_TT_INTEGER:
564 return v[n].i;
565
566 case MRBC_TT_FLOAT:
567 return v[n].d;
568
569 default:
570 ;
571 }
572
573 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be Integer or Float", n);
574 return 0;
575}
576
577
578//================================================================
591mrbc_int_t mrbc_arg_i2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_int_t default_value)
592{
593 if( argc < n ) return default_value;
594
595 return mrbc_arg_i( vm, v, argc, n );
596}
597
598
599//================================================================
611mrbc_float_t mrbc_arg_f(struct VM *vm, mrbc_value v[], int argc, int n)
612{
613 if( argc < n ) {
614 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
615 "wrong number of arguments (given %d, expected %d)", argc, n);
616 return 0;
617 }
618
619 switch(v[n].tt) {
620 case MRBC_TT_INTEGER:
621 return v[n].i;
622
623 case MRBC_TT_FLOAT:
624 return v[n].d;
625
626 default:
627 ;
628 }
629
630 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be Integer or Float", n);
631 return 0;
632}
633
634
635//================================================================
648mrbc_float_t mrbc_arg_f2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_float_t default_value)
649{
650 if( argc < n ) return default_value;
651
652 return mrbc_arg_f( vm, v, argc, n );
653}
654
655
656//================================================================
668const char * mrbc_arg_s(struct VM *vm, mrbc_value v[], int argc, int n)
669{
670 if( argc < n ) {
671 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
672 "wrong number of arguments (given %d, expected %d)", argc, n);
673 return 0;
674 }
675
676 switch(v[n].tt) {
677 case MRBC_TT_STRING:
678 return mrbc_string_cstr( &v[n] );
679
680 default:
681 ;
682 }
683
684 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be String", n);
685 return 0;
686}
687
688
689//================================================================
702const char * mrbc_arg_s2(struct VM *vm, mrbc_value v[], int argc, int n, const char *default_value)
703{
704 if( argc < n ) return default_value;
705
706 return mrbc_arg_s( vm, v, argc, n );
707}
708
709
710//================================================================
722int mrbc_arg_b(struct VM *vm, mrbc_value v[], int argc, int n)
723{
724 if( argc < n ) {
725 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
726 "wrong number of arguments (given %d, expected %d)", argc, n);
727 return 0;
728 }
729
730 switch(v[n].tt) {
731 case MRBC_TT_FALSE:
732 return 0;
733
734 case MRBC_TT_TRUE:
735 return 1;
736
737 default:
738 ;
739 }
740
741 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be true or false", n);
742 return 0;
743}
744
745
746//================================================================
759int mrbc_arg_b2(struct VM *vm, mrbc_value v[], int argc, int n, int default_value)
760{
761 if( argc < n ) return default_value;
762
763 return mrbc_arg_b( vm, v, argc, n );
764}
int mrbc_array_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_array.c:443
void mrbc_array_delete(mrbc_value *ary)
Definition c_array.c:113
int mrbc_hash_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_hash.c:292
void mrbc_hash_delete(mrbc_value *hash)
Definition c_hash.c:108
void mrbc_proc_delete(mrbc_value *val)
Definition c_proc.c:73
void mrbc_range_delete(mrbc_value *v)
Definition c_range.c:64
int mrbc_range_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_range.c:97
void mrbc_string_delete(mrbc_value *str)
Definition c_string.c:129
static char * mrbc_string_cstr(const mrbc_value *v)
Definition c_string.h:116
static int mrbc_string_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_string.h:94
void mrbc_instance_delete(mrbc_value *v)
Definition class.c:355
mrbc_value mrbc_send(struct VM *vm, mrbc_value *v, int argc, mrbc_value *recv, const char *method_name, int n_params,...)
Definition class.c:538
#define MRBC_CLASS(cls)
Definition class.h:51
void mrbc_raise(struct VM *vm, struct RClass *exc_cls, const char *msg)
Definition error.c:150
void mrbc_exception_delete(mrbc_value *value)
Definition error.c:133
void mrbc_raisef(struct VM *vm, struct RClass *exc_cls, const char *fstr,...)
Definition error.c:173
#define mrbc_israised(vm)
Definition error.h:37
Include at once the necessary header files.
mrbc_float_t d
Definition value.h:156
mrbc_vtype tt
Definition value.h:152
struct RClass * cls
Definition value.h:160
mrbc_int_t i
Definition value.h:154
Virtual Machine.
Definition vm.h:140
const char * mrbc_symid_to_str(mrbc_sym sym_id)
Definition symbol.c:238
int mrbc_arg_b2(struct VM *vm, mrbc_value v[], int argc, int n, int default_value)
Definition value.c:759
char * mrbc_to_s(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
Definition value.c:492
const char * mrbc_val_s2(struct VM *vm, const mrbc_value *val, const char *default_value)
Definition value.c:390
void(*const mrbc_delfunc[])(mrbc_value *)
Definition value.c:37
mrbc_int_t mrbc_to_i(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
Definition value.c:410
mrbc_int_t mrbc_val_i(struct VM *vm, const mrbc_value *val)
Definition value.c:264
const char * mrbc_val_s(struct VM *vm, const mrbc_value *val)
Definition value.c:362
mrbc_value * mrbc_arg(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:530
double mrbc_val_f2(struct VM *vm, const mrbc_value *val, double default_value)
Definition value.c:344
const char * mrbc_arg_s(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:668
int mrbc_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition value.c:66
mrbc_float_t mrbc_arg_f(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:611
mrbc_int_t mrbc_arg_i2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_int_t default_value)
Definition value.c:591
int mrbc_arg_b(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:722
mrbc_int_t mrbc_val_i2(struct VM *vm, const mrbc_value *val, mrbc_int_t default_value)
Definition value.c:295
mrbc_float_t mrbc_to_f(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
Definition value.c:451
int mrbc_strcpy(char *dest, int destsize, const char *src)
Definition value.c:239
mrbc_int_t mrbc_atoi(const char *s, int base)
Definition value.c:186
mrbc_float_t mrbc_arg_f2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_float_t default_value)
Definition value.c:648
const char * mrbc_arg_s2(struct VM *vm, mrbc_value v[], int argc, int n, const char *default_value)
Definition value.c:702
mrbc_int_t mrbc_arg_i(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:554
double mrbc_val_f(struct VM *vm, const mrbc_value *val)
Definition value.c:313
float mrbc_float_t
Definition value.h:51
int32_t mrbc_int_t
Definition value.h:45
static void mrbc_decref(mrbc_value *v)
Definition value.h:604
#define mrbc_symbol(o)
Definition value.h:196
#define mrbc_set_integer(p, n)
Definition value.h:199
#define mrbc_type(o)
Definition value.h:193
#define mrbc_set_float(p, n)
Definition value.h:200
@ MRBC_TT_FALSE
FalseClass.
Definition value.h:79
@ MRBC_TT_SYMBOL
Symbol.
Definition value.h:86
@ MRBC_TT_STRING
String.
Definition value.h:95
@ MRBC_TT_FLOAT
Float.
Definition value.h:85
@ MRBC_TT_INTEGER
Integer.
Definition value.h:83
@ MRBC_TT_EMPTY
Definition value.h:77
@ MRBC_TT_PROC
Proc.
Definition value.h:93
@ MRBC_TT_RANGE
Range.
Definition value.h:96
@ MRBC_TT_OBJECT
General instance.
Definition value.h:92
@ MRBC_TT_ARRAY
Array.
Definition value.h:94
@ MRBC_TT_MODULE
Module.
Definition value.h:88
@ MRBC_TT_TRUE
TrueClass.
Definition value.h:82
@ MRBC_TT_NIL
NilClass.
Definition value.h:78
@ MRBC_TT_HASH
Hash.
Definition value.h:97
@ MRBC_TT_CLASS
Class.
Definition value.h:87
struct RObject mrbc_value
Definition value.h:174
#define mrbc_float(o)
Definition value.h:195
#define mrbc_integer(o)
Definition value.h:194
Global configuration of mruby/c VM's.