This is a port of the mruby/c tutorial Chapter 03 to the mbed environment.
For details, refer to the following.
http://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/436
Note:There is a change in rtt0.h from the original source in the mruby/c. It was necessary for inclusion in C ++ source.
mrubyc/c_array.c@0:33feccbba3ff, 2017-02-15 (annotated)
- Committer:
- tk_takateku
- Date:
- Wed Feb 15 01:03:35 2017 +0000
- Revision:
- 0:33feccbba3ff
Commit before publishing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tk_takateku | 0:33feccbba3ff | 1 | #include <stddef.h> |
tk_takateku | 0:33feccbba3ff | 2 | |
tk_takateku | 0:33feccbba3ff | 3 | #include "c_array.h" |
tk_takateku | 0:33feccbba3ff | 4 | |
tk_takateku | 0:33feccbba3ff | 5 | #include "alloc.h" |
tk_takateku | 0:33feccbba3ff | 6 | #include "class.h" |
tk_takateku | 0:33feccbba3ff | 7 | #include "static.h" |
tk_takateku | 0:33feccbba3ff | 8 | #include "value.h" |
tk_takateku | 0:33feccbba3ff | 9 | |
tk_takateku | 0:33feccbba3ff | 10 | // Internal use only |
tk_takateku | 0:33feccbba3ff | 11 | // get size of array |
tk_takateku | 0:33feccbba3ff | 12 | static int array_size(mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 13 | { |
tk_takateku | 0:33feccbba3ff | 14 | mrb_value *array = v->value.obj; |
tk_takateku | 0:33feccbba3ff | 15 | return array->value.i; |
tk_takateku | 0:33feccbba3ff | 16 | } |
tk_takateku | 0:33feccbba3ff | 17 | |
tk_takateku | 0:33feccbba3ff | 18 | |
tk_takateku | 0:33feccbba3ff | 19 | // Array#!= |
tk_takateku | 0:33feccbba3ff | 20 | static void c_array_neq(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 21 | { |
tk_takateku | 0:33feccbba3ff | 22 | if( mrbc_eq(v, v+1) ){ |
tk_takateku | 0:33feccbba3ff | 23 | SET_FALSE_RETURN(); |
tk_takateku | 0:33feccbba3ff | 24 | } else { |
tk_takateku | 0:33feccbba3ff | 25 | SET_TRUE_RETURN(); |
tk_takateku | 0:33feccbba3ff | 26 | } |
tk_takateku | 0:33feccbba3ff | 27 | } |
tk_takateku | 0:33feccbba3ff | 28 | |
tk_takateku | 0:33feccbba3ff | 29 | // Array = empty? |
tk_takateku | 0:33feccbba3ff | 30 | static void c_array_empty(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 31 | { |
tk_takateku | 0:33feccbba3ff | 32 | if( array_size(v) > 0 ){ |
tk_takateku | 0:33feccbba3ff | 33 | SET_FALSE_RETURN(); |
tk_takateku | 0:33feccbba3ff | 34 | } else { |
tk_takateku | 0:33feccbba3ff | 35 | SET_TRUE_RETURN(); |
tk_takateku | 0:33feccbba3ff | 36 | } |
tk_takateku | 0:33feccbba3ff | 37 | } |
tk_takateku | 0:33feccbba3ff | 38 | |
tk_takateku | 0:33feccbba3ff | 39 | // Array = size |
tk_takateku | 0:33feccbba3ff | 40 | static void c_array_size(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 41 | { |
tk_takateku | 0:33feccbba3ff | 42 | int cnt = array_size(v); |
tk_takateku | 0:33feccbba3ff | 43 | SET_INT_RETURN( cnt ); |
tk_takateku | 0:33feccbba3ff | 44 | } |
tk_takateku | 0:33feccbba3ff | 45 | |
tk_takateku | 0:33feccbba3ff | 46 | // Array = [] |
tk_takateku | 0:33feccbba3ff | 47 | static void c_array_get(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 48 | { |
tk_takateku | 0:33feccbba3ff | 49 | int pos = GET_INT_ARG(0); |
tk_takateku | 0:33feccbba3ff | 50 | mrb_value *array = v->value.obj; |
tk_takateku | 0:33feccbba3ff | 51 | |
tk_takateku | 0:33feccbba3ff | 52 | if( pos >= 0 && pos < array->value.i ){ |
tk_takateku | 0:33feccbba3ff | 53 | *v = array[pos+1]; |
tk_takateku | 0:33feccbba3ff | 54 | } else { |
tk_takateku | 0:33feccbba3ff | 55 | SET_NIL_RETURN(); |
tk_takateku | 0:33feccbba3ff | 56 | } |
tk_takateku | 0:33feccbba3ff | 57 | } |
tk_takateku | 0:33feccbba3ff | 58 | |
tk_takateku | 0:33feccbba3ff | 59 | // Array = []= |
tk_takateku | 0:33feccbba3ff | 60 | static void c_array_set(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 61 | { |
tk_takateku | 0:33feccbba3ff | 62 | int pos = GET_INT_ARG(0); |
tk_takateku | 0:33feccbba3ff | 63 | mrb_value *array = v->value.obj; |
tk_takateku | 0:33feccbba3ff | 64 | |
tk_takateku | 0:33feccbba3ff | 65 | if( pos >= 0 && pos < array->value.i ){ |
tk_takateku | 0:33feccbba3ff | 66 | array[pos+1] = GET_ARG(1); |
tk_takateku | 0:33feccbba3ff | 67 | } else { |
tk_takateku | 0:33feccbba3ff | 68 | SET_NIL_RETURN(); |
tk_takateku | 0:33feccbba3ff | 69 | } |
tk_takateku | 0:33feccbba3ff | 70 | } |
tk_takateku | 0:33feccbba3ff | 71 | |
tk_takateku | 0:33feccbba3ff | 72 | // Array = operator + |
tk_takateku | 0:33feccbba3ff | 73 | static void c_array_plus(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 74 | { |
tk_takateku | 0:33feccbba3ff | 75 | // because realloc is not ready in alloc.c, |
tk_takateku | 0:33feccbba3ff | 76 | // use free and alloc |
tk_takateku | 0:33feccbba3ff | 77 | mrb_value *array1 = v->value.array; |
tk_takateku | 0:33feccbba3ff | 78 | mrb_value *array2 = GET_ARY_ARG(0).value.array; |
tk_takateku | 0:33feccbba3ff | 79 | int len1 = array1->value.i; |
tk_takateku | 0:33feccbba3ff | 80 | int len2 = array2->value.i; |
tk_takateku | 0:33feccbba3ff | 81 | mrb_value *new_array = (mrb_value *)mrbc_alloc(vm, sizeof(mrb_value)*(len1+len2+1)); |
tk_takateku | 0:33feccbba3ff | 82 | |
tk_takateku | 0:33feccbba3ff | 83 | if( new_array == NULL ) return; // ENOMEM |
tk_takateku | 0:33feccbba3ff | 84 | |
tk_takateku | 0:33feccbba3ff | 85 | new_array->tt = MRB_TT_FIXNUM; |
tk_takateku | 0:33feccbba3ff | 86 | new_array->value.i = len1+len2; |
tk_takateku | 0:33feccbba3ff | 87 | mrb_value *p = new_array + 1; |
tk_takateku | 0:33feccbba3ff | 88 | int i; |
tk_takateku | 0:33feccbba3ff | 89 | for( i=0 ; i<len1 ; i++ ){ |
tk_takateku | 0:33feccbba3ff | 90 | *p++ = array1[i+1]; |
tk_takateku | 0:33feccbba3ff | 91 | } |
tk_takateku | 0:33feccbba3ff | 92 | for( i=0 ; i<len2 ; i++ ){ |
tk_takateku | 0:33feccbba3ff | 93 | *p++ = array2[i+1]; |
tk_takateku | 0:33feccbba3ff | 94 | } |
tk_takateku | 0:33feccbba3ff | 95 | mrbc_free(vm, array1); |
tk_takateku | 0:33feccbba3ff | 96 | mrbc_free(vm, array2); |
tk_takateku | 0:33feccbba3ff | 97 | // return |
tk_takateku | 0:33feccbba3ff | 98 | v->value.array = new_array; |
tk_takateku | 0:33feccbba3ff | 99 | } |
tk_takateku | 0:33feccbba3ff | 100 | |
tk_takateku | 0:33feccbba3ff | 101 | |
tk_takateku | 0:33feccbba3ff | 102 | static void c_array_index(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 103 | { |
tk_takateku | 0:33feccbba3ff | 104 | int len = v->value.array->value.i; |
tk_takateku | 0:33feccbba3ff | 105 | mrb_value *array = v->value.array + 1; |
tk_takateku | 0:33feccbba3ff | 106 | mrb_value value = GET_ARG(0); |
tk_takateku | 0:33feccbba3ff | 107 | |
tk_takateku | 0:33feccbba3ff | 108 | int i; |
tk_takateku | 0:33feccbba3ff | 109 | for( i=0 ; i<len ; i++ ){ |
tk_takateku | 0:33feccbba3ff | 110 | // check EQ |
tk_takateku | 0:33feccbba3ff | 111 | if( mrbc_eq(array+i, &value) ) break; |
tk_takateku | 0:33feccbba3ff | 112 | } |
tk_takateku | 0:33feccbba3ff | 113 | if( i<len ){ |
tk_takateku | 0:33feccbba3ff | 114 | SET_INT_RETURN(i); |
tk_takateku | 0:33feccbba3ff | 115 | } else { |
tk_takateku | 0:33feccbba3ff | 116 | SET_NIL_RETURN(); |
tk_takateku | 0:33feccbba3ff | 117 | } |
tk_takateku | 0:33feccbba3ff | 118 | } |
tk_takateku | 0:33feccbba3ff | 119 | |
tk_takateku | 0:33feccbba3ff | 120 | static void c_array_first(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 121 | { |
tk_takateku | 0:33feccbba3ff | 122 | if( GET_TT_ARG(0) == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 123 | mrb_value *array = v->value.array + 1; |
tk_takateku | 0:33feccbba3ff | 124 | SET_RETURN( array[0] ); |
tk_takateku | 0:33feccbba3ff | 125 | } else { |
tk_takateku | 0:33feccbba3ff | 126 | SET_NIL_RETURN(); |
tk_takateku | 0:33feccbba3ff | 127 | } |
tk_takateku | 0:33feccbba3ff | 128 | } |
tk_takateku | 0:33feccbba3ff | 129 | |
tk_takateku | 0:33feccbba3ff | 130 | static void c_array_last(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 131 | { |
tk_takateku | 0:33feccbba3ff | 132 | if( GET_TT_ARG(0) == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 133 | int len = v->value.array->value.i; |
tk_takateku | 0:33feccbba3ff | 134 | mrb_value *array = v->value.array + 1; |
tk_takateku | 0:33feccbba3ff | 135 | SET_RETURN( array[len-1] ); |
tk_takateku | 0:33feccbba3ff | 136 | } else { |
tk_takateku | 0:33feccbba3ff | 137 | SET_NIL_RETURN(); |
tk_takateku | 0:33feccbba3ff | 138 | } |
tk_takateku | 0:33feccbba3ff | 139 | } |
tk_takateku | 0:33feccbba3ff | 140 | |
tk_takateku | 0:33feccbba3ff | 141 | static void c_array_pop(mrb_vm *vm, mrb_value *v) |
tk_takateku | 0:33feccbba3ff | 142 | { |
tk_takateku | 0:33feccbba3ff | 143 | mrb_object *obj = v->value.obj; |
tk_takateku | 0:33feccbba3ff | 144 | mrb_object *tmp = obj->next; |
tk_takateku | 0:33feccbba3ff | 145 | while( tmp->next ){ |
tk_takateku | 0:33feccbba3ff | 146 | obj = obj->next; |
tk_takateku | 0:33feccbba3ff | 147 | tmp = obj->next; |
tk_takateku | 0:33feccbba3ff | 148 | } |
tk_takateku | 0:33feccbba3ff | 149 | obj->next = tmp->next; |
tk_takateku | 0:33feccbba3ff | 150 | SET_INT_RETURN(tmp->value.i); |
tk_takateku | 0:33feccbba3ff | 151 | } |
tk_takateku | 0:33feccbba3ff | 152 | |
tk_takateku | 0:33feccbba3ff | 153 | |
tk_takateku | 0:33feccbba3ff | 154 | void mrbc_init_class_array(mrb_vm *vm) |
tk_takateku | 0:33feccbba3ff | 155 | { |
tk_takateku | 0:33feccbba3ff | 156 | // Array |
tk_takateku | 0:33feccbba3ff | 157 | mrbc_class_array = mrbc_class_alloc(vm, "Array", mrbc_class_object); |
tk_takateku | 0:33feccbba3ff | 158 | |
tk_takateku | 0:33feccbba3ff | 159 | mrbc_define_method(vm, mrbc_class_array, "!=", c_array_neq); |
tk_takateku | 0:33feccbba3ff | 160 | mrbc_define_method(vm, mrbc_class_array, "count", c_array_size); |
tk_takateku | 0:33feccbba3ff | 161 | mrbc_define_method(vm, mrbc_class_array, "length", c_array_size); |
tk_takateku | 0:33feccbba3ff | 162 | mrbc_define_method(vm, mrbc_class_array, "size", c_array_size); |
tk_takateku | 0:33feccbba3ff | 163 | mrbc_define_method(vm, mrbc_class_array, "+", c_array_plus); |
tk_takateku | 0:33feccbba3ff | 164 | mrbc_define_method(vm, mrbc_class_array, "empty?", c_array_empty); |
tk_takateku | 0:33feccbba3ff | 165 | mrbc_define_method(vm, mrbc_class_array, "[]", c_array_get); |
tk_takateku | 0:33feccbba3ff | 166 | mrbc_define_method(vm, mrbc_class_array, "at", c_array_get); |
tk_takateku | 0:33feccbba3ff | 167 | mrbc_define_method(vm, mrbc_class_array, "[]=", c_array_set); |
tk_takateku | 0:33feccbba3ff | 168 | mrbc_define_method(vm, mrbc_class_array, "index", c_array_index); |
tk_takateku | 0:33feccbba3ff | 169 | |
tk_takateku | 0:33feccbba3ff | 170 | |
tk_takateku | 0:33feccbba3ff | 171 | mrbc_define_method(vm, mrbc_class_array, "first", c_array_first); |
tk_takateku | 0:33feccbba3ff | 172 | mrbc_define_method(vm, mrbc_class_array, "last", c_array_last); |
tk_takateku | 0:33feccbba3ff | 173 | mrbc_define_method(vm, mrbc_class_array, "pop", c_array_pop); |
tk_takateku | 0:33feccbba3ff | 174 | } |
tk_takateku | 0:33feccbba3ff | 175 |