mruby/c VM Source Code release 4.0.0
Loading...
Searching...
No Matches
value.c
Go to the documentation of this file.
1
14
15/***** Feature test switches ************************************************/
16/***** System headers *******************************************************/
17//@cond
18#include "vm_config.h"
19#include <stdio.h>
20#include <string.h>
21#include <assert.h>
22//@endcond
23
24/***** Local headers ********************************************************/
25#include "mrubyc.h"
26
27/***** Constant values ******************************************************/
28/***** Macros ***************************************************************/
29/***** Typedefs *************************************************************/
30/***** Function prototypes **************************************************/
31/***** Local variables ******************************************************/
32/***** Global variables *****************************************************/
33//================================================================
39void (* const mrbc_delfunc[])(mrbc_value *) = {
40 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 mrbc_instance_delete, // MRBC_TT_OBJECT = 9,
42 mrbc_proc_delete, // MRBC_TT_PROC = 10,
43 mrbc_array_delete, // MRBC_TT_ARRAY = 11,
44#if MRBC_USE_STRING
45 mrbc_string_delete, // MRBC_TT_STRING = 12,
46#else
47 NULL,
48#endif
49 mrbc_range_delete, // MRBC_TT_RANGE = 13,
50 mrbc_hash_delete, // MRBC_TT_HASH = 14,
51 mrbc_exception_delete, // MRBC_TT_EXCEPTION = 15,
52};
53
54
55/***** Signal catching functions ********************************************/
56/***** Local functions ******************************************************/
57/***** Global functions *****************************************************/
58
59//================================================================
68int mrbc_compare(const mrbc_value *v1, const mrbc_value *v2)
69{
70#if MRBC_USE_FLOAT
71 mrbc_float_t d1, d2;
72#endif
73
74 // if TT_XXX is different
75 if( mrbc_type(*v1) != mrbc_type(*v2) ) {
76#if MRBC_USE_FLOAT
77 // but Numeric?
78 if( mrbc_type(*v1) == MRBC_TT_INTEGER && mrbc_type(*v2) == MRBC_TT_FLOAT ) {
79 d1 = v1->i;
80 d2 = v2->d;
81 goto CMP_FLOAT;
82 }
83 if( mrbc_type(*v1) == MRBC_TT_FLOAT && mrbc_type(*v2) == MRBC_TT_INTEGER ) {
84 d1 = v1->d;
85 d2 = v2->i;
86 goto CMP_FLOAT;
87 }
88#endif
89
90 // leak Empty?
91 if((mrbc_type(*v1) == MRBC_TT_EMPTY && mrbc_type(*v2) == MRBC_TT_NIL) ||
92 (mrbc_type(*v1) == MRBC_TT_NIL && mrbc_type(*v2) == MRBC_TT_EMPTY)) return 0;
93
94 // other case
95 return mrbc_type(*v1) - mrbc_type(*v2);
96 }
97
98 // check value
99 switch( mrbc_type(*v1) ) {
100 case MRBC_TT_NIL:
101 case MRBC_TT_FALSE:
102 case MRBC_TT_TRUE:
103 return 0;
104
105 case MRBC_TT_INTEGER:
106 return mrbc_integer(*v1) - mrbc_integer(*v2);
107
108 case MRBC_TT_SYMBOL: {
109 const char *str1 = mrbc_symid_to_str(mrbc_symbol(*v1));
110 const char *str2 = mrbc_symid_to_str(mrbc_symbol(*v2));
111 int diff = strlen(str1) - strlen(str2);
112 int len = diff < 0 ? strlen(str1) : strlen(str2);
113 int res = memcmp(str1, str2, len);
114 return (res != 0) ? res : diff;
115 }
116
117#if MRBC_USE_FLOAT
118 case MRBC_TT_FLOAT:
119 d1 = mrbc_float(*v1);
120 d2 = mrbc_float(*v2);
121 goto CMP_FLOAT;
122#endif
123
124 case MRBC_TT_CLASS:
125 case MRBC_TT_MODULE:
126 case MRBC_TT_OBJECT:
127 case MRBC_TT_PROC:
128 return (v1->cls > v2->cls) * 2 - (v1->cls != v2->cls);
129
130 case MRBC_TT_ARRAY:
131 return mrbc_array_compare( v1, v2 );
132
133#if MRBC_USE_STRING
134 case MRBC_TT_STRING:
135 return mrbc_string_compare( v1, v2 );
136#endif
137
138 case MRBC_TT_RANGE:
139 return mrbc_range_compare( v1, v2 );
140
141 case MRBC_TT_HASH:
142 return mrbc_hash_compare( v1, v2 );
143
144 default:
145 return 1;
146 }
147
148#if MRBC_USE_FLOAT
149 CMP_FLOAT:
150 return -1 + (d1 == d2) + (d1 > d2)*2; // caution: NaN == NaN is false
151#endif
152}
153
154
155#if defined(MRBC_ALLOC_VMID)
156//================================================================
161void mrbc_clear_vm_id(mrbc_value *v)
162{
163 switch( mrbc_type(*v) ) {
164 case MRBC_TT_OBJECT: mrbc_instance_clear_vm_id(v); break;
165 case MRBC_TT_PROC: mrbc_proc_clear_vm_id(v); break;
166 case MRBC_TT_ARRAY: mrbc_array_clear_vm_id(v); break;
167#if MRBC_USE_STRING
168 case MRBC_TT_STRING: mrbc_string_clear_vm_id(v); break;
169#endif
170 case MRBC_TT_RANGE: mrbc_range_clear_vm_id(v); break;
171 case MRBC_TT_HASH: mrbc_hash_clear_vm_id(v); break;
172
173 default:
174 // Nothing
175 break;
176 }
177}
178#endif
179
180
181//================================================================
188mrbc_int_t mrbc_atoi( const char *s, int base )
189{
190 int ret = 0;
191 int sign = 0;
192
193 REDO:
194 switch( *s ) {
195 case '-':
196 sign = 1;
197 // fall through.
198 case '+':
199 s++;
200 break;
201
202 case ' ':
203 s++;
204 goto REDO;
205 }
206
207 int ch;
208 while( (ch = *s++) != '\0' ) {
209 int n;
210
211 if( 'a' <= ch ) {
212 n = ch - 'a' + 10;
213 } else
214 if( 'A' <= ch ) {
215 n = ch - 'A' + 10;
216 } else
217 if( '0' <= ch && ch <= '9' ) {
218 n = ch - '0';
219 } else {
220 break;
221 }
222 if( n >= base ) break;
223
224 ret = ret * base + n;
225 }
226
227 if( sign ) ret = -ret;
228
229 return ret;
230}
231
232
233//================================================================
241int mrbc_strcpy( char *dest, int destsize, const char *src )
242{
243 int n = destsize;
244 if( n <= 0 ) return 0;
245
246 while( --n != 0 ) {
247 if( (*dest++ = *src++) == 0 ) goto RETURN;
248 }
249 *dest = 0;
250
251 RETURN:
252 return destsize - n - 1;
253}
254
255
256//================================================================
263void mrbc_format_float(char *buf, int bufsiz, mrbc_float_t flo)
264{
265 snprintf(buf, bufsiz, "%g", flo);
266 if( strpbrk(buf, ".e") ) return;
267
268 int len = strlen(buf);
269 mrbc_strcpy( buf + len, bufsiz - len, ".0" );
270}
271
272
273//================================================================
283mrbc_int_t mrbc_val_i(struct VM *vm, const mrbc_value *val)
284{
285 if( val == NULL ) return 0;
286
287 switch( mrbc_type(*val) ) {
288 case MRBC_TT_INTEGER:
289 return val->i;
290
291 case MRBC_TT_FLOAT:
292 return val->d;
293
294 default:
295 ;
296 }
297
298 mrbc_raise(vm, MRBC_CLASS(TypeError), "argument must be Integer or Float");
299 return 0;
300}
301
302
303//================================================================
314mrbc_int_t mrbc_val_i2(struct VM *vm, const mrbc_value *val, mrbc_int_t default_value )
315{
316 if( val == NULL || mrbc_type(*val) == MRBC_TT_EMPTY ) return default_value;
317
318 return mrbc_val_i( vm, val );
319}
320
321
322//================================================================
332double mrbc_val_f(struct VM *vm, const mrbc_value *val)
333{
334 if( val == NULL ) return 0;
335
336 switch( mrbc_type(*val) ) {
337 case MRBC_TT_INTEGER:
338 return val->i;
339
340 case MRBC_TT_FLOAT:
341 return val->d;
342
343 default:
344 ;
345 }
346
347 mrbc_raise(vm, MRBC_CLASS(TypeError), "argument must be Integer or Float");
348 return 0;
349}
350
351
352//================================================================
363double mrbc_val_f2(struct VM *vm, const mrbc_value *val, double default_value )
364{
365 if( val == NULL || mrbc_type(*val) == MRBC_TT_EMPTY ) return default_value;
366
367 return mrbc_val_f( vm, val );
368}
369
370
371//================================================================
381const char * mrbc_val_s(struct VM *vm, const mrbc_value *val)
382{
383 if( val == NULL ) return 0;
384
385 switch( mrbc_type(*val) ) {
386 case MRBC_TT_STRING:
387 return mrbc_string_cstr( val );
388
389 default:
390 ;
391 }
392
393 mrbc_raise(vm, MRBC_CLASS(TypeError), "argument must be String");
394 return 0;
395}
396
397
398//================================================================
409const char * mrbc_val_s2(struct VM *vm, const mrbc_value *val, const char * default_value )
410{
411 if( val == NULL || mrbc_type(*val) == MRBC_TT_EMPTY ) return default_value;
412
413 return mrbc_val_s( vm, val );
414}
415
416
417//================================================================
429mrbc_int_t mrbc_to_i(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
430{
431 if( val == NULL ) return 0;
432
433 switch( mrbc_type(*val) ) {
434 case MRBC_TT_EMPTY:
435 mrbc_raise(vm, MRBC_CLASS(TypeError), 0);
436 return 0;
437
438 case MRBC_TT_INTEGER:
439 break;
440
441 case MRBC_TT_FLOAT:
442 mrbc_set_integer(val, val->d);
443 break;
444
445 default:{
446 mrbc_value ret = mrbc_send( vm, v, argc, val, "to_i", 0 );
447 if( mrbc_israised(vm) ) return 0;
448
449 mrbc_decref( val );
450 *val = ret;
451 } break;
452 }
453
454 return val->i;
455}
456
457
458//================================================================
470mrbc_float_t mrbc_to_f(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
471{
472 if( val == NULL ) return 0;
473
474 switch( mrbc_type(*val) ) {
475 case MRBC_TT_EMPTY:
476 mrbc_raise(vm, MRBC_CLASS(TypeError), 0);
477 return 0;
478
479 case MRBC_TT_INTEGER:
480 mrbc_set_float(val, val->i);
481 break;
482
483 case MRBC_TT_FLOAT:
484 break;
485
486 default:{
487 mrbc_value ret = mrbc_send( vm, v, argc, val, "to_f", 0 );
488 if( mrbc_israised(vm) ) return 0;
489
490 mrbc_decref( val );
491 *val = ret;
492 } break;
493 }
494
495 return val->d;
496}
497
498
499//================================================================
511char * mrbc_to_s(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
512{
513 if( val == NULL ) return 0;
514
515 switch( mrbc_type(*val) ) {
516 case MRBC_TT_EMPTY:
517 mrbc_raise(vm, MRBC_CLASS(TypeError), 0);
518 return 0;
519
520 case MRBC_TT_STRING:
521 goto RETURN;
522
523 default:{
524 mrbc_value ret = mrbc_send( vm, v, argc, val, "to_s", 0 );
525 if( mrbc_israised(vm) ) return 0;
526
527 mrbc_decref( val );
528 *val = ret;
529 } break;
530 }
531
532 RETURN:
533 return mrbc_string_cstr( val );
534}
535
536
537//================================================================
549mrbc_value * mrbc_arg(struct VM *vm, mrbc_value v[], int argc, int n)
550{
551 if( argc < n ) {
552 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
553 "wrong number of arguments (given %d, expected %d)", argc, n);
554 return 0;
555 }
556
557 return &v[n];
558}
559
560
561//================================================================
573mrbc_int_t mrbc_arg_i(struct VM *vm, mrbc_value v[], int argc, int n)
574{
575 if( argc < n ) {
576 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
577 "wrong number of arguments (given %d, expected %d)", argc, n);
578 return 0;
579 }
580
581 switch( mrbc_type(v[n]) ) {
582 case MRBC_TT_INTEGER:
583 return v[n].i;
584
585 case MRBC_TT_FLOAT:
586 return v[n].d;
587
588 default:
589 ;
590 }
591
592 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be Integer or Float", n);
593 return 0;
594}
595
596
597//================================================================
610mrbc_int_t mrbc_arg_i2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_int_t default_value)
611{
612 if( argc < n ) return default_value;
613
614 return mrbc_arg_i( vm, v, argc, n );
615}
616
617
618//================================================================
630mrbc_float_t mrbc_arg_f(struct VM *vm, mrbc_value v[], int argc, int n)
631{
632 if( argc < n ) {
633 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
634 "wrong number of arguments (given %d, expected %d)", argc, n);
635 return 0;
636 }
637
638 switch( mrbc_type(v[n]) ) {
639 case MRBC_TT_INTEGER:
640 return v[n].i;
641
642 case MRBC_TT_FLOAT:
643 return v[n].d;
644
645 default:
646 ;
647 }
648
649 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be Integer or Float", n);
650 return 0;
651}
652
653
654//================================================================
667mrbc_float_t mrbc_arg_f2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_float_t default_value)
668{
669 if( argc < n ) return default_value;
670
671 return mrbc_arg_f( vm, v, argc, n );
672}
673
674
675//================================================================
687const char * mrbc_arg_s(struct VM *vm, mrbc_value v[], int argc, int n)
688{
689 if( argc < n ) {
690 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
691 "wrong number of arguments (given %d, expected %d)", argc, n);
692 return 0;
693 }
694
695 switch( mrbc_type(v[n]) ) {
696 case MRBC_TT_STRING:
697 return mrbc_string_cstr( &v[n] );
698
699 default:
700 ;
701 }
702
703 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be String", n);
704 return 0;
705}
706
707
708//================================================================
721const char * mrbc_arg_s2(struct VM *vm, mrbc_value v[], int argc, int n, const char *default_value)
722{
723 if( argc < n ) return default_value;
724
725 return mrbc_arg_s( vm, v, argc, n );
726}
727
728
729//================================================================
741int mrbc_arg_b(struct VM *vm, mrbc_value v[], int argc, int n)
742{
743 if( argc < n ) {
744 mrbc_raisef(vm, MRBC_CLASS(ArgumentError),
745 "wrong number of arguments (given %d, expected %d)", argc, n);
746 return 0;
747 }
748
749 switch( mrbc_type(v[n]) ) {
750 case MRBC_TT_FALSE:
751 return 0;
752
753 case MRBC_TT_TRUE:
754 return 1;
755
756 default:
757 ;
758 }
759
760 mrbc_raisef(vm, MRBC_CLASS(TypeError), "argument %d must be true or false", n);
761 return 0;
762}
763
764
765//================================================================
778int mrbc_arg_b2(struct VM *vm, mrbc_value v[], int argc, int n, int default_value)
779{
780 if( argc < n ) return default_value;
781
782 return mrbc_arg_b( vm, v, argc, n );
783}
#define mrbc_symbol(o)
Definition boxing_no.h:60
static void mrbc_set_float(mrbc_value *p, mrbc_float_t d)
Definition boxing_no.h:87
#define mrbc_type(o)
Definition boxing_no.h:57
struct RObject mrbc_value
Value object. Default version.
#define mrbc_float(o)
Definition boxing_no.h:59
#define mrbc_integer(o)
Definition boxing_no.h:58
static void mrbc_set_integer(mrbc_value *p, mrbc_int_t n)
Definition boxing_no.h:81
int mrbc_array_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_array.c:432
void mrbc_array_delete(mrbc_value *ary)
Definition c_array.c:105
int mrbc_hash_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_hash.c:284
void mrbc_hash_delete(mrbc_value *hash)
Definition c_hash.c:100
void mrbc_proc_delete(mrbc_value *val)
Definition c_proc.c:71
void mrbc_range_delete(mrbc_value *v)
Definition c_range.c:63
int mrbc_range_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_range.c:96
void mrbc_string_delete(mrbc_value *str)
Definition c_string.c:107
static char * mrbc_string_cstr(const mrbc_value *v)
Definition c_string.h:122
static int mrbc_string_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition c_string.h:100
void mrbc_instance_delete(mrbc_value *v)
Definition class.c:325
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:526
#define MRBC_CLASS(cls)
Definition class.h:55
void mrbc_raise(struct VM *vm, struct RClass *exc_cls, const char *msg)
Definition error.c:145
void mrbc_exception_delete(mrbc_value *value)
Definition error.c:128
void mrbc_raisef(struct VM *vm, struct RClass *exc_cls, const char *fstr,...)
Definition error.c:168
#define mrbc_israised(vm)
Definition error.h:38
Include at once the necessary header files.
mrbc_float_t d
Definition boxing_no.h:24
struct RClass * cls
Definition boxing_no.h:28
mrbc_int_t i
Definition boxing_no.h:22
Virtual Machine.
Definition vm.h:150
const char * mrbc_symid_to_str(mrbc_sym sym_id)
Definition symbol.c:242
int mrbc_arg_b2(struct VM *vm, mrbc_value v[], int argc, int n, int default_value)
Definition value.c:778
char * mrbc_to_s(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
Definition value.c:511
const char * mrbc_val_s2(struct VM *vm, const mrbc_value *val, const char *default_value)
Definition value.c:409
void(*const mrbc_delfunc[])(mrbc_value *)
Definition value.c:39
mrbc_int_t mrbc_to_i(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
Definition value.c:429
mrbc_int_t mrbc_val_i(struct VM *vm, const mrbc_value *val)
Definition value.c:283
const char * mrbc_val_s(struct VM *vm, const mrbc_value *val)
Definition value.c:381
mrbc_value * mrbc_arg(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:549
double mrbc_val_f2(struct VM *vm, const mrbc_value *val, double default_value)
Definition value.c:363
const char * mrbc_arg_s(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:687
int mrbc_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition value.c:68
mrbc_float_t mrbc_arg_f(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:630
mrbc_int_t mrbc_arg_i2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_int_t default_value)
Definition value.c:610
int mrbc_arg_b(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:741
mrbc_int_t mrbc_val_i2(struct VM *vm, const mrbc_value *val, mrbc_int_t default_value)
Definition value.c:314
mrbc_float_t mrbc_to_f(struct VM *vm, mrbc_value v[], int argc, mrbc_value *val)
Definition value.c:470
int mrbc_strcpy(char *dest, int destsize, const char *src)
Definition value.c:241
mrbc_int_t mrbc_atoi(const char *s, int base)
Definition value.c:188
mrbc_float_t mrbc_arg_f2(struct VM *vm, mrbc_value v[], int argc, int n, mrbc_float_t default_value)
Definition value.c:667
const char * mrbc_arg_s2(struct VM *vm, mrbc_value v[], int argc, int n, const char *default_value)
Definition value.c:721
mrbc_int_t mrbc_arg_i(struct VM *vm, mrbc_value v[], int argc, int n)
Definition value.c:573
void mrbc_format_float(char *buf, int bufsiz, mrbc_float_t flo)
Definition value.c:263
double mrbc_val_f(struct VM *vm, const mrbc_value *val)
Definition value.c:332
float mrbc_float_t
Definition value.h:52
int32_t mrbc_int_t
Definition value.h:47
static void mrbc_decref(mrbc_value *v)
Definition value.h:561
@ MRBC_TT_FALSE
FalseClass.
Definition value.h:82
@ MRBC_TT_SYMBOL
Symbol.
Definition value.h:89
@ MRBC_TT_STRING
String.
Definition value.h:98
@ MRBC_TT_FLOAT
Float.
Definition value.h:88
@ MRBC_TT_INTEGER
Integer.
Definition value.h:86
@ MRBC_TT_EMPTY
Definition value.h:80
@ MRBC_TT_PROC
Proc.
Definition value.h:96
@ MRBC_TT_RANGE
Range.
Definition value.h:99
@ MRBC_TT_OBJECT
General instance.
Definition value.h:95
@ MRBC_TT_ARRAY
Array.
Definition value.h:97
@ MRBC_TT_MODULE
Module.
Definition value.h:91
@ MRBC_TT_TRUE
TrueClass.
Definition value.h:85
@ MRBC_TT_NIL
NilClass.
Definition value.h:81
@ MRBC_TT_HASH
Hash.
Definition value.h:100
@ MRBC_TT_CLASS
Class.
Definition value.h:90
Global configuration of mruby/c VM's.