mruby/c VM Source Code release 3.4
Loading...
Searching...
No Matches
c_array.c
Go to the documentation of this file.
1
53
54/***** Feature test switches ************************************************/
55/***** System headers *******************************************************/
56//@cond
57#include "vm_config.h"
58#include <string.h>
59#include <assert.h>
60//@endcond
61
62/***** Local headers ********************************************************/
63#include "mrubyc.h"
64
65/***** Constat values *******************************************************/
66/***** Macros ***************************************************************/
67/***** Typedefs *************************************************************/
68/***** Function prototypes **************************************************/
69/***** Local variables ******************************************************/
70/***** Global variables *****************************************************/
71/***** Signal catching functions ********************************************/
72/***** Local functions ******************************************************/
73/***** Global functions *****************************************************/
74
75//================================================================
82mrbc_value mrbc_array_new(struct VM *vm, int size)
83{
84 mrbc_value value = {.tt = MRBC_TT_ARRAY};
85
86 /*
87 Allocate handle and data buffer.
88 */
89 mrbc_array *h = mrbc_alloc(vm, sizeof(mrbc_array));
90 if( !h ) return value; // ENOMEM
91
92 mrbc_value *data = mrbc_alloc(vm, sizeof(mrbc_value) * size);
93 if( !data ) { // ENOMEM
94 mrbc_raw_free( h );
95 return value;
96 }
97
98 MRBC_INIT_OBJECT_HEADER( h, "AR" );
99 h->data_size = size;
100 h->n_stored = 0;
101 h->data = data;
102
103 value.array = h;
104 return value;
105}
106
107
108//================================================================
114{
115 mrbc_array *h = ary->array;
116
117 mrbc_value *p1 = h->data;
118 const mrbc_value *p2 = p1 + h->n_stored;
119 while( p1 < p2 ) {
120 mrbc_decref(p1++);
121 }
122
124}
125
126
127#if defined(MRBC_ALLOC_VMID)
128//================================================================
133void mrbc_array_clear_vm_id(mrbc_value *ary)
134{
135 mrbc_array *h = ary->array;
136
137 mrbc_set_vm_id( h, 0 );
138
139 mrbc_value *p1 = h->data;
140 const mrbc_value *p2 = p1 + h->n_stored;
141 while( p1 < p2 ) {
142 mrbc_clear_vm_id(p1++);
143 }
144}
145#endif
146
147
148//================================================================
155int mrbc_array_resize(mrbc_value *ary, int size)
156{
157 if( size <= 0 ) size = 1;
158
159 mrbc_array *h = ary->array;
160 mrbc_value *data = mrbc_raw_realloc(h->data, sizeof(mrbc_value) * size);
161 if( !data ) return E_NOMEMORY_ERROR; // ENOMEM
162
163 h->data = data;
164 h->data_size = size;
165
166 return 0;
167}
168
169
170//================================================================
178int mrbc_array_set(mrbc_value *ary, int idx, mrbc_value *set_val)
179{
180 mrbc_array *h = ary->array;
181
182 if( idx < 0 ) {
183 idx = h->n_stored + idx;
184 if( idx < 0 ) return E_INDEX_ERROR;
185 }
186
187 // need resize?
188 if( idx >= h->data_size && mrbc_array_resize(ary, idx + 1) != 0 ) {
189 return E_NOMEMORY_ERROR; // ENOMEM
190 }
191
192 if( idx < h->n_stored ) {
193 // release existing data.
194 mrbc_decref( &h->data[idx] );
195 } else {
196 // clear empty cells.
197 for( int i = h->n_stored; i < idx; i++ ) {
198 h->data[i] = mrbc_nil_value();
199 }
200 h->n_stored = idx + 1;
201 }
202
203 h->data[idx] = *set_val;
204
205 return 0;
206}
207
208
209//================================================================
217{
218 mrbc_array *h = ary->array;
219
220 if( idx < 0 ) idx = h->n_stored + idx;
221 if( idx < 0 || idx >= h->n_stored ) return mrbc_nil_value();
222
223 return h->data[idx];
224}
225
226
227//================================================================
235{
236 mrbc_array *h = ary->array;
237
238 if( idx < 0 ) idx = h->n_stored + idx;
239 if( idx < 0 || idx >= h->n_stored ) return NULL;
240
241 return &h->data[idx];
242}
243
244
245//================================================================
253{
254 mrbc_array *h = ary->array;
255
256 if( h->n_stored >= h->data_size ) {
257 int size = h->data_size + 6;
258 if( mrbc_array_resize(ary, size) != 0 ) return E_NOMEMORY_ERROR; // ENOMEM
259 }
260
261 h->data[h->n_stored++] = *set_val;
262
263 return 0;
264}
265
266
267//================================================================
275{
276 mrbc_array *ha_d = ary->array;
277 mrbc_array *ha_s = set_val->array;
278 int new_size = ha_d->n_stored + ha_s->n_stored;
279
280 if( new_size > ha_d->data_size ) {
281 if( mrbc_array_resize(ary, new_size) != 0 )
282 return E_NOMEMORY_ERROR; // ENOMEM
283 }
284
285 memcpy( &ha_d->data[ha_d->n_stored], ha_s->data,
286 sizeof(mrbc_value) * ha_s->n_stored );
287 ha_d->n_stored += ha_s->n_stored;
288
289 return 0;
290}
291
292
293//================================================================
300{
301 mrbc_array *h = ary->array;
302
303 if( h->n_stored <= 0 ) return mrbc_nil_value();
304 return h->data[--h->n_stored];
305}
306
307
308//================================================================
316{
317 return mrbc_array_insert(ary, 0, set_val);
318}
319
320
321//================================================================
328{
329 mrbc_array *h = ary->array;
330
331 if( h->n_stored <= 0 ) return mrbc_nil_value();
332
333 mrbc_value ret = h->data[0];
334 memmove(h->data, h->data+1, sizeof(mrbc_value) * --h->n_stored);
335
336 return ret;
337}
338
339
340//================================================================
348int mrbc_array_insert(mrbc_value *ary, int idx, mrbc_value *set_val)
349{
350 mrbc_array *h = ary->array;
351
352 if( idx < 0 ) {
353 idx = h->n_stored + idx + 1;
354 if( idx < 0 ) return E_INDEX_ERROR;
355 }
356
357 // need resize?
358 int size = 0;
359 if( idx >= h->data_size ) {
360 size = idx + 1;
361 } else if( h->n_stored >= h->data_size ) {
362 size = h->data_size + 1;
363 }
364 if( size && mrbc_array_resize(ary, size) != 0 ) {
365 return E_NOMEMORY_ERROR; // ENOMEM
366 }
367
368 // move datas.
369 if( idx < h->n_stored ) {
370 memmove(h->data + idx + 1, h->data + idx,
371 sizeof(mrbc_value) * (h->n_stored - idx));
372 }
373
374 // set data
375 h->data[idx] = *set_val;
376 h->n_stored++;
377
378 // clear empty cells if need.
379 if( idx >= h->n_stored ) {
380 for( int i = h->n_stored-1; i < idx; i++ ) {
381 h->data[i] = mrbc_nil_value();
382 }
383 h->n_stored = idx + 1;
384 }
385
386 return 0;
387}
388
389
390//================================================================
398{
399 mrbc_array *h = ary->array;
400
401 if( idx < 0 ) idx = h->n_stored + idx;
402 if( idx < 0 || idx >= h->n_stored ) return mrbc_nil_value();
403
404 mrbc_value ret = h->data[idx];
405 h->n_stored--;
406 if( idx < h->n_stored ) {
407 memmove(h->data + idx, h->data + idx + 1,
408 sizeof(mrbc_value) * (h->n_stored - idx));
409 }
410
411 return ret;
412}
413
414
415//================================================================
421{
422 mrbc_array *h = ary->array;
423
424 mrbc_value *p1 = h->data;
425 const mrbc_value *p2 = p1 + h->n_stored;
426 while( p1 < p2 ) {
427 mrbc_decref(p1++);
428 }
429
430 h->n_stored = 0;
431}
432
433
434//================================================================
443int mrbc_array_compare(const mrbc_value *v1, const mrbc_value *v2)
444{
445 for( int i = 0; ; i++ ) {
446 if( i >= mrbc_array_size(v1) || i >= mrbc_array_size(v2) ) {
447 return mrbc_array_size(v1) - mrbc_array_size(v2);
448 }
449
450 int res = mrbc_compare( &v1->array->data[i], &v2->array->data[i] );
451 if( res != 0 ) return res;
452 }
453}
454
455
456//================================================================
463void mrbc_array_minmax(mrbc_value *ary, mrbc_value **pp_min_value, mrbc_value **pp_max_value)
464{
465 mrbc_array *h = ary->array;
466
467 if( h->n_stored == 0 ) {
468 *pp_min_value = NULL;
469 *pp_max_value = NULL;
470 return;
471 }
472
473 mrbc_value *p_min_value = h->data;
474 mrbc_value *p_max_value = h->data;
475
476 for( int i = 1; i < h->n_stored; i++ ) {
477 if( mrbc_compare( &h->data[i], p_min_value ) < 0 ) {
478 p_min_value = &h->data[i];
479 }
480 if( mrbc_compare( &h->data[i], p_max_value ) > 0 ) {
481 p_max_value = &h->data[i];
482 }
483 }
484
485 *pp_min_value = p_min_value;
486 *pp_max_value = p_max_value;
487}
488
489
490//================================================================
497mrbc_value mrbc_array_dup(struct VM *vm, const mrbc_value *ary)
498{
499 mrbc_array *sh = ary->array;
500
501 mrbc_value dv = mrbc_array_new(vm, sh->n_stored);
502 if( dv.array == NULL ) return dv; // ENOMEM
503
504 memcpy( dv.array->data, sh->data, sizeof(mrbc_value) * sh->n_stored );
505 dv.array->n_stored = sh->n_stored;
506
507 mrbc_value *p1 = dv.array->data;
508 const mrbc_value *p2 = p1 + dv.array->n_stored;
509 while( p1 < p2 ) {
510 mrbc_incref(p1++);
511 }
512
513 return dv;
514}
515
516
517//================================================================
529mrbc_value mrbc_array_divide(struct VM *vm, mrbc_value *src, int pos)
530{
531 mrbc_array *ha_s = src->array;
532 if( pos < 0 ) pos = 0;
533 int new_size = ha_s->n_stored - pos;
534 if( new_size < 0 ) new_size = 0;
535 int remain_size = ha_s->n_stored - new_size;
536
537 mrbc_value ret = mrbc_array_new(vm, new_size);
538 if( ret.array == NULL ) return ret; // ENOMEM
539 mrbc_array *ha_r = ret.array;
540
541 memcpy( ha_r->data, ha_s->data + remain_size, sizeof(mrbc_value) * new_size );
542 ha_s->n_stored = remain_size;
543 mrbc_array_resize( src, remain_size );
544 ha_r->n_stored = new_size;
545
546 return ret;
547}
548
549//================================================================
556int mrbc_array_index(const mrbc_value *ary, const mrbc_value *val)
557{
558 int n = ary->array->n_stored;
559 for( int i = 0; i < n; i++ ) {
560 if( mrbc_compare(&ary->array->data[i], val) == 0 ) return i;
561 }
562 return -1;
563}
564
565
566//================================================================
574{
575 mrbc_value ret = mrbc_array_dup(vm, ary);
576
577 mrbc_array_uniq_self( &ret );
578 return ret;
579}
580
581
582//================================================================
589{
590 mrbc_array *ah = ary->array;
591 int size = ah->n_stored;
592
593 for( int i = 0; i < size-1; i++ ) {
594 for( int j = i+1; j < size; j++ ) {
595 if( mrbc_compare( &ah->data[i], &ah->data[j] ) != 0 ) continue;
596
597 mrbc_decref( &ah->data[j] );
598 int rest = --size - j;
599 if( rest == 0 ) break;
600
601 memmove( &ah->data[j], &ah->data[j+1], sizeof(mrbc_value) * rest );
602 j--;
603 }
604 }
605
606 int ret = ah->n_stored - size;
607 ah->n_stored = size;
608
609 return ret;
610}
611
612
613//================================================================
616static void c_array_new(struct VM *vm, mrbc_value v[], int argc)
617{
618 /*
619 in case of new()
620 */
621 if( argc == 0 ) {
622 mrbc_value ret = mrbc_array_new(vm, 0);
623 if( ret.array == NULL ) return; // ENOMEM
624
625 SET_RETURN(ret);
626 return;
627 }
628
629 /*
630 in case of new(num)
631 */
632 if( argc == 1 && mrbc_type(v[1]) == MRBC_TT_INTEGER && mrbc_integer(v[1]) >= 0 ) {
633 int num = mrbc_integer(v[1]);
634 mrbc_value ret = mrbc_array_new(vm, num);
635 if( ret.array == NULL ) return; // ENOMEM
636
637 if( num > 0 ) {
638 mrbc_array_set(&ret, num - 1, &mrbc_nil_value());
639 }
640 SET_RETURN(ret);
641 return;
642 }
643
644 /*
645 in case of new(num, value)
646 */
647 if( argc == 2 && mrbc_type(v[1]) == MRBC_TT_INTEGER && mrbc_integer(v[1]) >= 0 ) {
648 int num = mrbc_integer(v[1]);
649 mrbc_value ret = mrbc_array_new(vm, num);
650 if( ret.array == NULL ) return; // ENOMEM
651
652 for( int i = 0; i < num; i++ ) {
653 mrbc_incref(&v[2]);
654 mrbc_array_set(&ret, i, &v[2]);
655 }
656 SET_RETURN(ret);
657 return;
658 }
659
660 /*
661 other case
662 */
663 mrbc_raise( vm, MRBC_CLASS(ArgumentError), 0 );
664}
665
666
667//================================================================
670static void c_array_add(struct VM *vm, mrbc_value v[], int argc)
671{
672 if( mrbc_type(v[1]) != MRBC_TT_ARRAY ) {
673 mrbc_raise( vm, MRBC_CLASS(TypeError), 0 );
674 return;
675 }
676
677 mrbc_array *h1 = v[0].array;
678 mrbc_array *h2 = v[1].array;
679
680 mrbc_value value = mrbc_array_new(vm, h1->n_stored + h2->n_stored);
681 if( value.array == NULL ) return; // ENOMEM
682
683 memcpy( value.array->data, h1->data,
684 sizeof(mrbc_value) * h1->n_stored );
685 memcpy( value.array->data + h1->n_stored, h2->data,
686 sizeof(mrbc_value) * h2->n_stored );
687 value.array->n_stored = h1->n_stored + h2->n_stored;
688
689 mrbc_value *p1 = value.array->data;
690 const mrbc_value *p2 = p1 + value.array->n_stored;
691 while( p1 < p2 ) {
692 mrbc_incref(p1++);
693 }
694
696 SET_RETURN(value);
697}
698
699
700//================================================================
703static void c_array_get(struct VM *vm, mrbc_value v[], int argc)
704{
705 /*
706 in case of Array[...] -> Array
707 */
708 if( mrbc_type(v[0]) == MRBC_TT_CLASS ) {
709 mrbc_value ret = mrbc_array_new(vm, argc);
710 if( ret.array == NULL ) return; // ENOMEM
711
712 memcpy( ret.array->data, &v[1], sizeof(mrbc_value) * argc );
713 for( int i = 1; i <= argc; i++ ) {
714 mrbc_type(v[i]) = MRBC_TT_EMPTY;
715 }
716 ret.array->n_stored = argc;
717
718 SET_RETURN(ret);
719 return;
720 }
721
722 /*
723 in case of self[nth] -> object | nil
724 */
725 if( argc == 1 && mrbc_type(v[1]) == MRBC_TT_INTEGER ) {
726 mrbc_value ret = mrbc_array_get(v, mrbc_integer(v[1]));
727 mrbc_incref(&ret);
728 SET_RETURN(ret);
729 return;
730 }
731
732 /*
733 in case of self[start, length] -> Array | nil
734 */
735 if( argc == 2 && mrbc_type(v[1]) == MRBC_TT_INTEGER && mrbc_type(v[2]) == MRBC_TT_INTEGER ) {
736 int len = mrbc_array_size(&v[0]);
737 int idx = mrbc_integer(v[1]);
738 if( idx < 0 ) idx += len;
739 if( idx < 0 ) goto RETURN_NIL;
740
741 int size = (mrbc_integer(v[2]) < (len - idx)) ? mrbc_integer(v[2]) : (len - idx);
742 // min( mrbc_integer(v[2]), (len - idx) )
743 if( size < 0 ) goto RETURN_NIL;
744
745 mrbc_value ret = mrbc_array_new(vm, size);
746 if( ret.array == NULL ) return; // ENOMEM
747
748 for( int i = 0; i < size; i++ ) {
749 mrbc_value val = mrbc_array_get(v, mrbc_integer(v[1]) + i);
750 mrbc_incref(&val);
751 mrbc_array_push(&ret, &val);
752 }
753
754 SET_RETURN(ret);
755 return;
756 }
757
758 /*
759 other case
760 */
761 mrbc_raise( vm, MRBC_CLASS(ArgumentError), 0 );
762 return;
763
764 RETURN_NIL:
766}
767
768
769//================================================================
772static void c_array_set(struct VM *vm, mrbc_value v[], int argc)
773{
774 /*
775 in case of self[nth] = val
776 */
777 if( argc == 2 && v[1].tt == MRBC_TT_INTEGER ) {
778 if( mrbc_array_set(v, mrbc_integer(v[1]), &v[2]) != 0 ) {
779 mrbc_raise( vm, MRBC_CLASS(IndexError), "too small for array");
780 return;
781 }
782
783 // return val
784 mrbc_incref(&v[2]);
785 mrbc_decref(&v[0]);
786 v[0] = v[2];
787 v[2].tt = MRBC_TT_EMPTY;
788 return;
789 }
790
791 /*
792 in case of self[start, length] = val
793 */
794 if( argc == 3 && v[1].tt == MRBC_TT_INTEGER && v[2].tt == MRBC_TT_INTEGER ) {
795 int pos = mrbc_integer(v[1]);
796 int len = mrbc_integer(v[2]);
797
798 if( pos < 0 ) {
799 pos = v[0].array->n_stored + pos;
800 if( pos < 0 ) {
801 mrbc_raise( vm, MRBC_CLASS(IndexError), "index too small for array");
802 return;
803 }
804 } else if( pos > v[0].array->n_stored ) {
805 mrbc_array_set( &v[0], pos-1, &mrbc_nil_value() );
806 len = 0;
807 }
808 if( len < 0 ) {
809 mrbc_raise( vm, MRBC_CLASS(IndexError), "negative length");
810 return;
811 }
812 if( pos+len > v[0].array->n_stored ) {
813 len = v[0].array->n_stored - pos;
814 }
815
816 // split 2 part
817 mrbc_value v1 = mrbc_array_divide(vm, &v[0], pos+len);
818 mrbc_array *ha0 = v[0].array;
819
820 // delete data from tail.
821 for( int i = 0; i < len; i++ ) {
822 mrbc_decref( &ha0->data[--ha0->n_stored] );
823 }
824
825 // append data
826 if( v[3].tt == MRBC_TT_ARRAY ) {
827 mrbc_array_push_m(&v[0], &v[3]);
828 for( int i = 0; i < v[3].array->n_stored; i++ ) {
829 mrbc_incref( &v[3].array->data[i] );
830 }
831 } else {
832 mrbc_incref(&v[3]);
833 mrbc_array_push(&v[0], &v[3]);
834 }
835
836 mrbc_array_push_m(&v[0], &v1);
838
839 // return val
840 mrbc_decref(&v[0]);
841 v[0] = v[3];
842 v[3].tt = MRBC_TT_EMPTY;
843 return;
844 }
845
846 /*
847 other case
848 */
849 mrbc_raise( vm, MRBC_CLASS(ArgumentError), 0 );
850}
851
852
853//================================================================
856static void c_array_clear(struct VM *vm, mrbc_value v[], int argc)
857{
859}
860
861
862//================================================================
865static void c_array_delete_at(struct VM *vm, mrbc_value v[], int argc)
866{
867 if( argc == 1 && mrbc_type(v[1]) == MRBC_TT_INTEGER ) {
869 SET_RETURN(val);
870 } else {
871 mrbc_raise( vm, MRBC_CLASS(ArgumentError), 0 );
872 }
873}
874
875
876//================================================================
879static void c_array_empty(struct VM *vm, mrbc_value v[], int argc)
880{
881 int n = mrbc_array_size(v);
882
883 if( n ) {
885 } else {
887 }
888}
889
890
891//================================================================
894static void c_array_size(struct VM *vm, mrbc_value v[], int argc)
895{
896 int n = mrbc_array_size(v);
897
899}
900
901
902//================================================================
905static void c_array_include(struct VM *vm, mrbc_value v[], int argc)
906{
907 SET_BOOL_RETURN(0 < mrbc_array_include(&v[0], &v[1]));
908}
909
910
911//================================================================
914static void c_array_and(struct VM *vm, mrbc_value v[], int argc)
915{
916 if (v[1].tt != MRBC_TT_ARRAY) {
917 mrbc_raisef( vm, MRBC_CLASS(TypeError), "no implicit conversion into %s", "Array");
918 return;
919 }
920 mrbc_value result = mrbc_array_new(vm, 0);
921 for( int i = 0; i < v[0].array->n_stored; i++) {
922 mrbc_value *data = &v[0].array->data[i];
923 if (0 < mrbc_array_include(&v[1], data) && 0 == mrbc_array_include(&result, data))
924 {
925 mrbc_array_push(&result, data);
926 }
927 }
928 SET_RETURN(result);
929}
930
931
932//================================================================
935static void c_array_or(struct VM *vm, mrbc_value v[], int argc)
936{
937 if (v[1].tt != MRBC_TT_ARRAY) {
938 mrbc_raisef( vm, MRBC_CLASS(TypeError), "no implicit conversion into %s", "Array");
939 return;
940 }
941 mrbc_value result = mrbc_array_new(vm, 0);
942 for( int i = 0; i < v[0].array->n_stored; i++) {
943 mrbc_value *data = &v[0].array->data[i];
944 if (0 == mrbc_array_include(&result, data))
945 {
946 mrbc_array_push(&result, data);
947 }
948 }
949
950 for( int i = 0; i < v[1].array->n_stored; i++) {
951 mrbc_value *data = &v[1].array->data[i];
952 if (0 == mrbc_array_include(&result, data))
953 {
954 mrbc_array_push(&result, data);
955 }
956 }
957 SET_RETURN(result);
958}
959
960
961//================================================================
964static void c_array_first(struct VM *vm, mrbc_value v[], int argc)
965{
966 mrbc_value val = mrbc_array_get(v, 0);
967 mrbc_incref(&val);
968 SET_RETURN(val);
969}
970
971
972//================================================================
975static void c_array_last(struct VM *vm, mrbc_value v[], int argc)
976{
977 mrbc_value val = mrbc_array_get(v, -1);
978 mrbc_incref(&val);
979 SET_RETURN(val);
980}
981
982
983//================================================================
986static void c_array_push(struct VM *vm, mrbc_value v[], int argc)
987{
988 mrbc_array_push(&v[0], &v[1]);
989 mrbc_type(v[1]) = MRBC_TT_EMPTY;
990}
991
992
993//================================================================
996static void c_array_pop(struct VM *vm, mrbc_value v[], int argc)
997{
998 /*
999 in case of pop() -> object | nil
1000 */
1001 if( argc == 0 ) {
1002 mrbc_value val = mrbc_array_pop(v);
1003 SET_RETURN(val);
1004 return;
1005 }
1006
1007 /*
1008 in case of pop(n) -> Array
1009 */
1010 if( argc == 1 && mrbc_type(v[1]) == MRBC_TT_INTEGER ) {
1011 int pos = mrbc_array_size(&v[0]) - v[1].i;
1012 mrbc_value val = mrbc_array_divide(vm, &v[0], pos);
1013 SET_RETURN(val);
1014 return;
1015 }
1016
1017 mrbc_raise( vm, MRBC_CLASS(ArgumentError), 0 );
1018}
1019
1020
1021//================================================================
1024static void c_array_unshift(struct VM *vm, mrbc_value v[], int argc)
1025{
1026 mrbc_array_unshift(&v[0], &v[1]);
1027 mrbc_type(v[1]) = MRBC_TT_EMPTY;
1028}
1029
1030
1031//================================================================
1034static void c_array_shift(struct VM *vm, mrbc_value v[], int argc)
1035{
1036 /*
1037 in case of pop() -> object | nil
1038 */
1039 if( argc == 0 ) {
1041 SET_RETURN(val);
1042 return;
1043 }
1044
1045 /*
1046 in case of pop(n) -> Array
1047 */
1048 if( argc == 1 && mrbc_type(v[1]) == MRBC_TT_INTEGER ) {
1049 mrbc_value val = mrbc_array_divide(vm, &v[0], v[1].i);
1050
1051 // swap v[0] and val
1052 mrbc_array tmp = *v[0].array;
1053 v[0].array->data_size = val.array->data_size;
1054 v[0].array->n_stored = val.array->n_stored;
1055 v[0].array->data = val.array->data;
1056
1057 val.array->data_size = tmp.data_size;
1058 val.array->n_stored = tmp.n_stored;
1059 val.array->data = tmp.data;
1060
1061 SET_RETURN(val);
1062 return;
1063 }
1064
1065 mrbc_raise( vm, MRBC_CLASS(ArgumentError), 0 );
1066}
1067
1068
1069//================================================================
1072static void c_array_dup(struct VM *vm, mrbc_value v[], int argc)
1073{
1074 SET_RETURN( mrbc_array_dup( vm, &v[0] ) );
1075}
1076
1077
1078//================================================================
1081static void c_array_min(struct VM *vm, mrbc_value v[], int argc)
1082{
1083 // Subset of Array#min, not support min(n).
1084
1085 mrbc_value *p_min_value, *p_max_value;
1086
1087 mrbc_array_minmax(&v[0], &p_min_value, &p_max_value);
1088 if( p_min_value == NULL ) {
1090 return;
1091 }
1092
1093 mrbc_incref(p_min_value);
1094 SET_RETURN(*p_min_value);
1095}
1096
1097
1098//================================================================
1101static void c_array_max(struct VM *vm, mrbc_value v[], int argc)
1102{
1103 // Subset of Array#max, not support max(n).
1104
1105 mrbc_value *p_min_value, *p_max_value;
1106
1107 mrbc_array_minmax(&v[0], &p_min_value, &p_max_value);
1108 if( p_max_value == NULL ) {
1110 return;
1111 }
1112
1113 mrbc_incref(p_max_value);
1114 SET_RETURN(*p_max_value);
1115}
1116
1117
1118//================================================================
1121static void c_array_minmax(struct VM *vm, mrbc_value v[], int argc)
1122{
1123 // Subset of Array#minmax, not support minmax(n).
1124
1125 mrbc_value *p_min_value, *p_max_value;
1126 mrbc_value nil = mrbc_nil_value();
1127 mrbc_value ret = mrbc_array_new(vm, 2);
1128
1129 mrbc_array_minmax(&v[0], &p_min_value, &p_max_value);
1130 if( p_min_value == NULL ) p_min_value = &nil;
1131 if( p_max_value == NULL ) p_max_value = &nil;
1132
1133 mrbc_incref(p_min_value);
1134 mrbc_incref(p_max_value);
1135 mrbc_array_set(&ret, 0, p_min_value);
1136 mrbc_array_set(&ret, 1, p_max_value);
1137
1138 SET_RETURN(ret);
1139}
1140
1141
1142//================================================================
1145static void c_array_uniq(struct VM *vm, mrbc_value v[], int argc)
1146{
1147 // subset of Array#uniq
1148
1149 if( mrbc_c_block_given(vm, v, argc) ) {
1150 mrbc_raise(vm, MRBC_CLASS(NotImplementedError), "Block are not supported");
1151 return;
1152 }
1153
1154 mrbc_value ret = mrbc_array_uniq( vm, &v[0] );
1155 SET_RETURN( ret );
1156}
1157
1158
1159//================================================================
1162static void c_array_uniq_self(struct VM *vm, mrbc_value v[], int argc)
1163{
1164 // subset of Array#uniq!
1165
1166 if( mrbc_c_block_given(vm, v, argc) ) {
1167 mrbc_raise(vm, MRBC_CLASS(NotImplementedError), "Block are not supported");
1168 return;
1169 }
1170
1171 int n = mrbc_array_uniq_self( &v[0] );
1172 if( n == 0 ) SET_NIL_RETURN();
1173}
1174
1175
1176#if MRBC_USE_STRING
1177//================================================================
1180static void c_array_inspect(struct VM *vm, mrbc_value v[], int argc)
1181{
1182 if( v[0].tt == MRBC_TT_CLASS ) {
1183 v[0] = mrbc_string_new_cstr(vm, mrbc_symid_to_str( v[0].cls->sym_id ));
1184 return;
1185 }
1186
1187 mrbc_value ret = mrbc_string_new_cstr(vm, "[");
1188 if( !ret.string ) goto RETURN_NIL; // ENOMEM
1189
1190 for( int i = 0; i < mrbc_array_size(v); i++ ) {
1191 if( i != 0 ) mrbc_string_append_cstr( &ret, ", " );
1192
1193 mrbc_value v1 = mrbc_array_get(v, i);
1194 mrbc_value s1 = mrbc_send( vm, v, argc, &v1, "inspect", 0 );
1195 mrbc_string_append( &ret, &s1 );
1196 mrbc_string_delete( &s1 );
1197 }
1198
1199 mrbc_string_append_cstr( &ret, "]" );
1200
1201 SET_RETURN(ret);
1202 return;
1203
1204 RETURN_NIL:
1206}
1207
1208
1209//================================================================
1212static void c_array_join_1(struct VM *vm, mrbc_value v[], int argc,
1213 mrbc_value *src, mrbc_value *ret, mrbc_value *separator)
1214{
1215 if( mrbc_array_size(src) == 0 ) return;
1216
1217 int i = 0;
1218 int flag_error = 0;
1219 while( !flag_error ) {
1220 if( mrbc_type(src->array->data[i]) == MRBC_TT_ARRAY ) {
1221 c_array_join_1(vm, v, argc, &src->array->data[i], ret, separator);
1222 } else {
1223 mrbc_value v1 = mrbc_send( vm, v, argc, &src->array->data[i], "to_s", 0 );
1224 flag_error |= mrbc_string_append( ret, &v1 );
1225 mrbc_decref(&v1);
1226 }
1227 if( ++i >= mrbc_array_size(src) ) break; // normal return.
1228 flag_error |= mrbc_string_append( ret, separator );
1229 }
1230}
1231
1232static void c_array_join(struct VM *vm, mrbc_value v[], int argc)
1233{
1234 mrbc_value ret = mrbc_string_new(vm, NULL, 0);
1235 if( !ret.string ) goto RETURN_NIL; // ENOMEM
1236
1237 mrbc_value separator = (argc == 0) ? mrbc_string_new_cstr(vm, "") :
1238 mrbc_send( vm, v, argc, &v[1], "to_s", 0 );
1239
1240 c_array_join_1(vm, v, argc, &v[0], &ret, &separator );
1241 mrbc_decref(&separator);
1242
1243 SET_RETURN(ret);
1244 return;
1245
1246 RETURN_NIL:
1248}
1249
1250#endif
1251
1252
1253/* MRBC_AUTOGEN_METHOD_TABLE
1254
1255 CLASS("Array")
1256 FILE("_autogen_class_array.h")
1257
1258 METHOD( "new", c_array_new )
1259 METHOD( "+", c_array_add )
1260 METHOD( "[]", c_array_get )
1261 METHOD( "at", c_array_get )
1262 METHOD( "[]=", c_array_set )
1263 METHOD( "<<", c_array_push )
1264 METHOD( "clear", c_array_clear )
1265 METHOD( "delete_at", c_array_delete_at )
1266 METHOD( "empty?", c_array_empty )
1267 METHOD( "size", c_array_size )
1268 METHOD( "length", c_array_size )
1269 METHOD( "count", c_array_size )
1270 METHOD( "include?", c_array_include )
1271 METHOD( "&", c_array_and )
1272 METHOD( "|", c_array_or )
1273 METHOD( "first", c_array_first )
1274 METHOD( "last", c_array_last )
1275 METHOD( "push", c_array_push )
1276 METHOD( "pop", c_array_pop )
1277 METHOD( "shift", c_array_shift )
1278 METHOD( "unshift", c_array_unshift )
1279 METHOD( "dup", c_array_dup )
1280 METHOD( "min", c_array_min )
1281 METHOD( "max", c_array_max )
1282 METHOD( "minmax", c_array_minmax )
1283 METHOD( "uniq", c_array_uniq )
1284 METHOD( "uniq!", c_array_uniq_self )
1285#if MRBC_USE_STRING
1286 METHOD( "inspect", c_array_inspect )
1287 METHOD( "to_s", c_array_inspect )
1288 METHOD( "join", c_array_join )
1289#endif
1290*/
1291#include "_autogen_class_array.h"
void * mrbc_raw_realloc(void *ptr, unsigned int size)
Definition alloc.c:796
void mrbc_raw_free(void *ptr)
Definition alloc.c:695
int mrbc_array_push(mrbc_value *ary, mrbc_value *set_val)
Definition c_array.c:252
mrbc_value mrbc_array_pop(mrbc_value *ary)
Definition c_array.c:299
int mrbc_array_set(mrbc_value *ary, int idx, mrbc_value *set_val)
Definition c_array.c:178
mrbc_value mrbc_array_get(const mrbc_value *ary, int idx)
Definition c_array.c:216
mrbc_value * mrbc_array_get_p(const mrbc_value *ary, int idx)
Definition c_array.c:234
mrbc_value mrbc_array_divide(struct VM *vm, mrbc_value *src, int pos)
Definition c_array.c:529
mrbc_value mrbc_array_new(struct VM *vm, int size)
Definition c_array.c:82
mrbc_value mrbc_array_remove(mrbc_value *ary, int idx)
Definition c_array.c:397
int mrbc_array_uniq_self(mrbc_value *ary)
Definition c_array.c:588
void mrbc_array_minmax(mrbc_value *ary, mrbc_value **pp_min_value, mrbc_value **pp_max_value)
Definition c_array.c:463
int mrbc_array_resize(mrbc_value *ary, int size)
Definition c_array.c:155
mrbc_value mrbc_array_uniq(struct VM *vm, const mrbc_value *ary)
Definition c_array.c:573
mrbc_value mrbc_array_shift(mrbc_value *ary)
Definition c_array.c:327
void mrbc_array_clear(mrbc_value *ary)
Definition c_array.c:420
int mrbc_array_insert(mrbc_value *ary, int idx, mrbc_value *set_val)
Definition c_array.c:348
mrbc_value mrbc_array_dup(struct VM *vm, const mrbc_value *ary)
Definition c_array.c:497
int mrbc_array_push_m(mrbc_value *ary, mrbc_value *set_val)
Definition c_array.c:274
int mrbc_array_unshift(mrbc_value *ary, mrbc_value *set_val)
Definition c_array.c:315
int mrbc_array_index(const mrbc_value *ary, const mrbc_value *val)
Definition c_array.c:556
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
static void mrbc_array_delete_handle(mrbc_value *ary)
Definition c_array.h:103
static int mrbc_array_size(const mrbc_value *ary)
Definition c_array.h:81
struct RArray mrbc_array
Array object.
static int mrbc_array_include(const mrbc_value *ary, const mrbc_value *val)
Definition c_array.h:94
void mrbc_string_delete(mrbc_value *str)
Definition c_string.c:129
int mrbc_string_append(mrbc_value *s1, const mrbc_value *s2)
Definition c_string.c:210
mrbc_value mrbc_string_new(struct VM *vm, const void *src, int len)
Definition c_string.c:62
static mrbc_value mrbc_string_new_cstr(struct VM *vm, const char *src)
Definition c_string.h:85
static int mrbc_string_append_cstr(mrbc_value *s1, const char *s2)
Definition c_string.h:128
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_raisef(struct VM *vm, struct RClass *exc_cls, const char *fstr,...)
Definition error.c:173
Include at once the necessary header files.
uint16_t n_stored
num of stored.
Definition c_array.h:44
uint16_t data_size
data buffer size.
Definition c_array.h:43
mrbc_value * data
pointer to allocated memory.
Definition c_array.h:45
struct RString * string
Definition value.h:164
mrbc_vtype tt
Definition value.h:152
mrbc_int_t i
Definition value.h:154
struct RArray * array
Definition value.h:163
Virtual Machine.
Definition vm.h:140
const char * mrbc_symid_to_str(mrbc_sym sym_id)
Definition symbol.c:238
int mrbc_compare(const mrbc_value *v1, const mrbc_value *v2)
Definition value.c:66
static void mrbc_decref(mrbc_value *v)
Definition value.h:604
#define MRBC_INIT_OBJECT_HEADER(p, t)
Definition value.h:307
#define SET_BOOL_RETURN(n)
Definition value.h:278
#define SET_INT_RETURN(n)
Definition value.h:283
#define mrbc_nil_value()
Definition value.h:210
static void mrbc_decref_empty(mrbc_value *v)
Definition value.h:622
#define SET_NIL_RETURN()
Definition value.h:266
static void mrbc_incref(mrbc_value *v)
Definition value.h:589
@ E_INDEX_ERROR
Definition value.h:112
@ E_NOMEMORY_ERROR
Definition value.h:108
#define SET_TRUE_RETURN()
Definition value.h:274
#define mrbc_type(o)
Definition value.h:193
@ MRBC_TT_INTEGER
Integer.
Definition value.h:83
@ MRBC_TT_EMPTY
Definition value.h:77
@ MRBC_TT_ARRAY
Array.
Definition value.h:94
@ MRBC_TT_CLASS
Class.
Definition value.h:87
struct RObject mrbc_value
Definition value.h:174
#define SET_RETURN(n)
Definition value.h:261
#define mrbc_integer(o)
Definition value.h:194
#define SET_FALSE_RETURN()
Definition value.h:270
static int mrbc_c_block_given(struct VM *vm, mrbc_value v[], int argc)
Definition vm.h:205
Global configuration of mruby/c VM's.