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_hash.c
- Committer:
- tk_takateku
- Date:
- 2017-02-15
- Revision:
- 0:33feccbba3ff
File content as of revision 0:33feccbba3ff:
#include <stddef.h> #include "c_hash.h" #include "alloc.h" #include "class.h" #include "static.h" #include "value.h" static void c_hash_size(mrb_vm *vm, mrb_value *v) { mrb_value *hash = v->value.obj; SET_INT_RETURN(hash->value.obj->value.i); } // Hash = [] static void c_hash_get(mrb_vm *vm, mrb_value *v) { mrb_value *hash = v->value.obj->value.obj; int i; int n = hash->value.i; // hash size mrb_value key = GET_ARG(0); // search key // ptr: 1st entry(key) of hash mrb_value *ptr = &hash[1]; for( i=0 ; i<n ; i++ ){ if( mrbc_eq(ptr, &key) ){ SET_RETURN( *(ptr+1) ); return; } ptr += 2; } SET_NIL_RETURN(); } // Hash = []= static void c_hash_set(mrb_vm *vm, mrb_value *v) { mrb_value *hash = v->value.obj->value.obj; int i; int n = hash[0].value.i; // hash size mrb_value key = GET_ARG(0); // search key mrb_value val = GET_ARG(1); // new value mrb_value *ptr = &hash[1]; for( i=0 ; i<n ; i++ ){ if( mrbc_eq(ptr, &key) ){ *(ptr+1) = val; // Change value return; } } // key was not found // add hash entry (key and val) int new_size = (n+1)*2 + 1; // use alloc instead of realloc, realloc has some bugs? mrb_value *new_hash = (mrb_value *)mrbc_alloc(vm, sizeof(mrb_value)*new_size); if( new_hash == NULL ) return; // ENOMEM mrb_value *src = &hash[1]; mrb_value *dst = &new_hash[1]; for( i=0 ; i<n ; i++ ){ *dst++ = *src++; // copy key *dst++ = *src++; // copy value } new_hash[0].tt = MRB_TT_FIXNUM; new_hash[0].value.i = n+1; *dst++ = key; *dst = val; mrbc_free(vm, v->value.obj->value.obj); v->value.obj->value.obj = new_hash; } void mrbc_init_class_hash(mrb_vm *vm) { // Hash mrbc_class_hash = mrbc_class_alloc(vm, "Hash", mrbc_class_object); mrbc_define_method(vm, mrbc_class_hash, "size", c_hash_size); mrbc_define_method(vm, mrbc_class_hash, "[]", c_hash_get); mrbc_define_method(vm, mrbc_class_hash, "[]=", c_hash_set); }