This is a port of the mruby/c tutorial Chapter 03 to the mbed environment.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers c_array.c Source File

c_array.c

00001 #include <stddef.h>
00002 
00003 #include "c_array.h "
00004 
00005 #include "alloc.h"
00006 #include "class.h "
00007 #include "static.h"
00008 #include "value.h "
00009 
00010 // Internal use only
00011 // get size of array
00012 static int array_size(mrb_value *v)
00013 {
00014   mrb_value *array = v->value.obj;
00015   return array->value.i;
00016 }
00017 
00018 
00019 // Array#!=
00020 static void c_array_neq(mrb_vm *vm, mrb_value *v)
00021 {
00022   if( mrbc_eq(v, v+1) ){
00023     SET_FALSE_RETURN();
00024   } else {
00025     SET_TRUE_RETURN();
00026   }
00027 }
00028 
00029 // Array = empty?
00030 static void c_array_empty(mrb_vm *vm, mrb_value *v)
00031 {
00032   if( array_size(v) > 0 ){
00033     SET_FALSE_RETURN();
00034   } else {
00035     SET_TRUE_RETURN();
00036   }
00037 }
00038 
00039 // Array = size
00040 static void c_array_size(mrb_vm *vm, mrb_value *v)
00041 {
00042   int cnt = array_size(v);
00043   SET_INT_RETURN( cnt );
00044 }
00045 
00046 // Array = []
00047 static void c_array_get(mrb_vm *vm, mrb_value *v)
00048 {
00049   int pos = GET_INT_ARG(0);
00050   mrb_value *array = v->value.obj;
00051 
00052   if( pos >= 0 && pos < array->value.i ){
00053     *v = array[pos+1];
00054   } else {
00055     SET_NIL_RETURN();
00056   }
00057 }
00058 
00059 // Array = []=
00060 static void c_array_set(mrb_vm *vm, mrb_value *v)
00061 {
00062   int pos = GET_INT_ARG(0);
00063   mrb_value *array = v->value.obj;
00064 
00065   if( pos >= 0 && pos < array->value.i ){
00066     array[pos+1] = GET_ARG(1);
00067   } else {
00068     SET_NIL_RETURN();
00069   }
00070 }
00071 
00072 // Array = operator +
00073 static void c_array_plus(mrb_vm *vm, mrb_value *v)
00074 {
00075   // because realloc is not ready in alloc.c,
00076   // use free and alloc
00077   mrb_value *array1 = v->value.array;
00078   mrb_value *array2 = GET_ARY_ARG(0).value.array;
00079   int len1 = array1->value.i;
00080   int len2 = array2->value.i;
00081   mrb_value *new_array = (mrb_value *)mrbc_alloc(vm, sizeof(mrb_value)*(len1+len2+1));
00082 
00083   if( new_array == NULL ) return;  // ENOMEM
00084 
00085   new_array->tt = MRB_TT_FIXNUM;
00086   new_array->value.i = len1+len2;
00087   mrb_value *p = new_array + 1;
00088   int i;
00089   for( i=0 ; i<len1 ; i++ ){
00090     *p++ = array1[i+1];
00091   }
00092   for( i=0 ; i<len2 ; i++ ){
00093     *p++ = array2[i+1];
00094   }
00095   mrbc_free(vm, array1);
00096   mrbc_free(vm, array2);
00097   // return
00098   v->value.array = new_array;
00099 }
00100 
00101 
00102 static void c_array_index(mrb_vm *vm, mrb_value *v)
00103 {
00104   int len = v->value.array->value.i;
00105   mrb_value *array = v->value.array + 1;
00106   mrb_value value = GET_ARG(0);
00107 
00108   int i;
00109   for( i=0 ; i<len ; i++ ){
00110     // check EQ
00111     if( mrbc_eq(array+i, &value) ) break;
00112   }
00113   if( i<len ){
00114     SET_INT_RETURN(i);
00115   } else {
00116     SET_NIL_RETURN();
00117   }
00118 }
00119 
00120 static void c_array_first(mrb_vm *vm, mrb_value *v)
00121 {
00122   if( GET_TT_ARG(0) == MRB_TT_FIXNUM ){
00123     mrb_value *array = v->value.array + 1;
00124     SET_RETURN( array[0] );
00125   } else {
00126     SET_NIL_RETURN();
00127   }
00128 }
00129 
00130 static void c_array_last(mrb_vm *vm, mrb_value *v)
00131 {
00132   if( GET_TT_ARG(0) == MRB_TT_FIXNUM ){
00133     int len = v->value.array->value.i;
00134     mrb_value *array = v->value.array + 1;
00135     SET_RETURN( array[len-1] );
00136   } else {
00137     SET_NIL_RETURN();
00138   }
00139 }
00140 
00141 static void c_array_pop(mrb_vm *vm, mrb_value *v)
00142 {
00143     mrb_object *obj = v->value.obj;
00144     mrb_object *tmp = obj->next;
00145     while( tmp->next ){
00146         obj = obj->next;
00147         tmp = obj->next;
00148     }
00149     obj->next = tmp->next;
00150     SET_INT_RETURN(tmp->value.i);
00151 }
00152 
00153 
00154 void mrbc_init_class_array(mrb_vm *vm)
00155 {
00156   // Array
00157   mrbc_class_array = mrbc_class_alloc(vm, "Array", mrbc_class_object);
00158 
00159   mrbc_define_method(vm, mrbc_class_array, "!=", c_array_neq);
00160   mrbc_define_method(vm, mrbc_class_array, "count", c_array_size);
00161   mrbc_define_method(vm, mrbc_class_array, "length", c_array_size);
00162   mrbc_define_method(vm, mrbc_class_array, "size", c_array_size);
00163   mrbc_define_method(vm, mrbc_class_array, "+", c_array_plus);
00164   mrbc_define_method(vm, mrbc_class_array, "empty?", c_array_empty);
00165   mrbc_define_method(vm, mrbc_class_array, "[]", c_array_get);
00166   mrbc_define_method(vm, mrbc_class_array, "at", c_array_get);
00167   mrbc_define_method(vm, mrbc_class_array, "[]=", c_array_set);
00168   mrbc_define_method(vm, mrbc_class_array, "index", c_array_index);
00169 
00170 
00171   mrbc_define_method(vm, mrbc_class_array, "first", c_array_first);
00172   mrbc_define_method(vm, mrbc_class_array, "last", c_array_last);
00173   mrbc_define_method(vm, mrbc_class_array, "pop", c_array_pop);
00174 }
00175