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/class.c
- Committer:
- tk_takateku
- Date:
- 2017-02-15
- Revision:
- 0:33feccbba3ff
File content as of revision 0:33feccbba3ff:
/*! @file @brief <pre> Copyright (C) 2015-2016 Kyushu Institute of Technology. Copyright (C) 2015-2016 Shimane IT Open-Innovation Center. This file is distributed under BSD 3-Clause License. </pre> */ #include "value.h" #include "class.h" #include "static.h" #include "console.h" #include "c_array.h" #include "c_hash.h" #include "c_numeric.h" #include "c_string.h" #include "c_symbol.h" #include "c_range.h" //================================================================ /*!@brief find class from a object @param vm @param obj @return pointer to mrb_class */ mrb_class *find_class_by_object(mrb_vm *vm, mrb_object *obj) { mrb_class *cls = mrbc_class_object; switch( obj->tt ){ case MRB_TT_ARRAY: cls = mrbc_class_array; break; case MRB_TT_HASH: cls = mrbc_class_hash; break; case MRB_TT_FIXNUM: cls = mrbc_class_fixnum; break; case MRB_TT_SYMBOL: cls = mrbc_class_symbol; break; case MRB_TT_FALSE: cls = mrbc_class_false; break; case MRB_TT_TRUE: cls = mrbc_class_true; break; #if MRBC_USE_FLOAT case MRB_TT_FLOAT: cls = mrbc_class_float; break; #endif #if MRBC_USE_STRING case MRB_TT_STRING: cls = mrbc_class_string; break; #endif default: break; } return cls; } //================================================================ /*!@brief find method from @param vm @param recv @param sym_id @return */ mrb_proc *find_method(mrb_vm *vm, mrb_value recv, mrb_sym sym_id) { mrb_class *cls = find_class_by_object(vm, &recv); while( cls != 0 ) { mrb_proc *proc = cls->procs; while( proc != 0 ) { if( proc->sym_id == sym_id ) { return proc; } proc = proc->next; } cls = cls->super; } return 0; } void mrbc_define_method(mrb_vm *vm, mrb_class *cls, const char *name, mrb_func_t cfunc) { mrb_proc *rproc = mrbc_rproc_alloc(vm, name); rproc->c_func = 1; // c-func rproc->next = cls->procs; cls->procs = rproc; rproc->func.func = cfunc; } void mrbc_define_method_proc(mrb_vm *vm, mrb_class *cls, mrb_sym sym_id, mrb_proc *rproc) { rproc->c_func = 0; rproc->sym_id = sym_id; rproc->next = cls->procs; cls->procs = rproc; } // Object - puts void c_puts(mrb_vm *vm, mrb_value *v) { mrb_value *arg0 = v+1; switch( arg0->tt ){ case MRB_TT_FIXNUM: console_printf("%d", arg0->value.i); break; case MRB_TT_NIL: console_printf(""); break; case MRB_TT_TRUE: console_printf("true"); break; case MRB_TT_FALSE: console_printf("false"); break; #if MRBC_USE_FLOAT case MRB_TT_FLOAT: console_printf("%f", arg0->value.d); break; #endif #if MRBC_USE_STRING case MRB_TT_STRING: console_printf("%s", arg0->value.str); break; #endif case MRB_TT_RANGE:{ mrb_value *ptr = arg0->value.range; if( ptr[0].tt == MRB_TT_TRUE ){ console_printf("%d...%d", ptr[1].value.i, ptr[2].value.i); } else { console_printf("%d..%d", ptr[1].value.i, ptr[2].value.i); } } break; default: console_printf("Not supported: MRB_TT_XX(%d)", arg0->tt); break; } console_printf("\n"); } // Object != void c_object_neq(mrb_vm *vm, mrb_value *v) { if( mrbc_eq(v, &GET_ARG(0)) ){ SET_FALSE_RETURN(); } else { SET_TRUE_RETURN(); } } static void mrbc_init_class_object(mrb_vm *vm) { // Class mrbc_class_object = mrbc_class_alloc(vm, "Object", 0); // Methods mrbc_define_method(vm, mrbc_class_object, "puts", c_puts); mrbc_define_method(vm, mrbc_class_object, "!=", c_object_neq); } // =============== FalseClass void c_false_ne(mrb_vm *vm, mrb_value *v) { mrb_object *arg0 = v+1; if( arg0->tt == MRB_TT_FALSE ){ SET_FALSE_RETURN(); } else { SET_TRUE_RETURN(); } } void c_false_not(mrb_vm *vm, mrb_value *v) { SET_TRUE_RETURN(); } static void mrbc_init_class_false(mrb_vm *vm) { // Class mrbc_class_false = mrbc_class_alloc(vm, "FalseClass", mrbc_class_object); // Methods mrbc_define_method(vm, mrbc_class_false, "!=", c_false_ne); mrbc_define_method(vm, mrbc_class_false, "!", c_false_not); } // =============== TrueClass void c_true_ne(mrb_vm *vm, mrb_value *v) { mrb_object *arg0 = v+1; if( arg0->tt == MRB_TT_TRUE ){ SET_FALSE_RETURN(); } else { SET_TRUE_RETURN(); } } void c_true_not(mrb_vm *vm, mrb_value *v) { SET_FALSE_RETURN(); } static void mrbc_init_class_true(mrb_vm *vm) { // Class mrbc_class_true = mrbc_class_alloc(vm, "TrueClass", mrbc_class_object); // Methods mrbc_define_method(vm, mrbc_class_true, "!=", c_true_ne); mrbc_define_method(vm, mrbc_class_true, "!", c_true_not); } void mrbc_init_class(void) { mrbc_init_class_object(0); mrbc_init_class_false(0); mrbc_init_class_true(0); mrbc_init_class_fixnum(0); mrbc_init_class_symbol(0); #if MRBC_USE_FLOAT mrbc_init_class_float(0); #endif #if MRBC_USE_STRING mrbc_init_class_string(0); #endif mrbc_init_class_array(0); mrbc_init_class_range(0); mrbc_init_class_hash(0); }