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_numeric.c Source File

c_numeric.c

00001 #include <stdio.h>
00002 
00003 #include "vm_config.h"
00004 #include "c_numeric.h "
00005 #include "alloc.h"
00006 #include "class.h "
00007 #include "static.h"
00008 #include "value.h "
00009 #include "console.h "
00010 
00011 static void c_fixnum_eq(mrb_vm *vm, mrb_value *v)
00012 {
00013   console_printf ("ERROR ==\n");
00014 }
00015 
00016 // Operator %
00017 static void c_fixnum_mod(mrb_vm *vm, mrb_value *v)
00018 {
00019   int num = GET_INT_ARG(0);
00020   SET_INT_RETURN( v->value.i % num );
00021 }
00022 
00023 // Operator <=>
00024 static void c_fixnum_comp(mrb_vm *vm, mrb_value *v)
00025 {
00026   int num = GET_INT_ARG(0);
00027   if(v->value.i > num){
00028   SET_INT_RETURN(1);
00029   }else if(v->value.i == num){
00030   SET_INT_RETURN(0);
00031   }else{
00032   SET_INT_RETURN(-1);
00033   }
00034 }
00035 
00036 // Unary Operator ~; bit operation NOT
00037 static void c_fixnum_deny(mrb_vm *vm, mrb_value *v)
00038 {
00039   SET_INT_RETURN( (v->value.i + 1) * (-1)  );
00040 }
00041 
00042 
00043 // Operator &; bit operation AND
00044 static void c_fixnum_and(mrb_vm *vm, mrb_value *v)
00045 {
00046   int num = GET_INT_ARG(0);
00047   SET_INT_RETURN(v->value.i & num);
00048 }
00049 
00050 // x-bit left shift for x
00051 static int32_t shift(int32_t x, int32_t y)
00052 {
00053   if( y >= 33 ){
00054     x = 0;
00055   } else if( y >= 0 ){
00056     x <<= y;
00057   } else if( y > -33 ){
00058     x = x >> -y;
00059   } else {
00060     x = 0;
00061   }
00062   return x;
00063 }
00064 
00065 // Operator <<; bit operation LEFT_SHIFT
00066 static void c_fixnum_lshift(mrb_vm *vm, mrb_value *v)
00067 {
00068   int num = GET_INT_ARG(0);
00069   SET_INT_RETURN( shift(v->value.i, num) );
00070 }
00071 
00072 // Operator >>; bit operation RIGHT_SHIFT
00073 static void c_fixnum_rshift(mrb_vm *vm, mrb_value *v)
00074 {
00075   int num = GET_INT_ARG(0);
00076   SET_INT_RETURN( shift(v->value.i, -num) );
00077 }
00078 
00079 #if MRBC_USE_STRING
00080 static void c_fixnum_to_s(mrb_vm *vm, mrb_value *v)
00081 {
00082   int num = v->value.i;
00083   int i = 0, j = 0;
00084   char buf[10];
00085   int sign = 0;
00086 
00087   if( num < 0 ){
00088     sign = 1;
00089     num = -num;
00090   }
00091   do {
00092     buf[i++] = (num % 10) + '0';
00093     num = num / 10;
00094   } while( num > 0 );
00095   if( sign ){
00096     buf[i] = '-';
00097   } else {
00098     i--;
00099   }
00100   char *str = (char *)mrbc_alloc(vm, i+2);
00101   if( str == NULL ) return;  // ENOMEM
00102   while( i>=0 ){
00103     str[j++] = buf[i--];
00104   }
00105   str[j] = 0;
00106   v->tt = MRB_TT_STRING;
00107   v->value.str = str;
00108 }
00109 #endif
00110 
00111 
00112 
00113 void mrbc_init_class_fixnum(mrb_vm *vm)
00114 {
00115   // Fixnum
00116   mrbc_class_fixnum = mrbc_class_alloc(vm, "Fixnum", mrbc_class_object);
00117   mrbc_define_method(vm, mrbc_class_fixnum, "==", c_fixnum_eq);
00118   mrbc_define_method(vm, mrbc_class_fixnum, "%", c_fixnum_mod);
00119   mrbc_define_method(vm, mrbc_class_fixnum, "<=>", c_fixnum_comp);
00120   mrbc_define_method(vm, mrbc_class_fixnum, "~", c_fixnum_deny);
00121   mrbc_define_method(vm, mrbc_class_fixnum, "&", c_fixnum_and);
00122   mrbc_define_method(vm, mrbc_class_fixnum, "<<", c_fixnum_lshift);
00123   mrbc_define_method(vm, mrbc_class_fixnum, ">>", c_fixnum_rshift);
00124 #if MRBC_USE_STRING
00125   mrbc_define_method(vm, mrbc_class_fixnum, "to_s", c_fixnum_to_s);
00126 #endif
00127 }
00128 
00129 
00130 // Float
00131 #if MRBC_USE_FLOAT
00132 
00133 void mrbc_init_class_float(mrb_vm *vm)
00134 {
00135   // Float
00136   mrbc_class_float = mrbc_class_alloc(vm, "Float", mrbc_class_object);
00137 
00138 }
00139 
00140 #endif
00141