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

symbol.c

Go to the documentation of this file.
00001 /*! @file
00002   @brief
00003   Symbol
00004 
00005   <pre>
00006   Copyright (C) 2015-2016 Kyushu Institute of Technology.
00007   Copyright (C) 2015-2016 Shimane IT Open-Innovation Center.
00008 
00009   This file is distributed under BSD 3-Clause License.
00010 
00011   </pre>
00012 */
00013 
00014 #include <string.h>
00015 #include "symbol.h"
00016 #include "console.h "
00017 
00018 
00019 struct SYM_INDEX {
00020   uint16_t hash;    //!< hash value, returned by calc_hash().
00021   char    *pos;     //!< point to the symbol string. maybe in sym_table[].
00022 };
00023 
00024 
00025 static struct SYM_INDEX sym_index[MAX_SYMBOLS_COUNT];
00026 static int sym_index_pos;   // point to the last(free) sym_index array.
00027 static char  sym_table[MAX_SYMBOLS_SIZE];   // symbol string table.
00028 static char *sym_table_pos = sym_table; // point to the last(free) sym_table.
00029 
00030 
00031 //================================================================
00032 /*! Caliculate hash value.
00033 
00034   @param  str       Target string.
00035   @return uint16_t  Hash value.
00036 */
00037 static uint16_t calc_hash (const char *str)
00038 {
00039   uint16_t h = 0;
00040 
00041   while( *str != '\0' ) {
00042     h = h * 37 + *str;
00043     str++;
00044   }
00045   return h;
00046 }
00047 
00048 
00049 //================================================================
00050 /*! Add symbol to symbol table.
00051 
00052   @param  str       Target string.
00053   @return mrb_sym   Symbol value.
00054   @retval -1        If error occurred.
00055 */
00056 mrb_sym add_sym (const char *str)
00057 {
00058   mrb_sym sym_id = str_to_symid (str);
00059 
00060   if( sym_id < 0 ) {
00061     // check overflow.
00062     if( sym_index_pos >= MAX_SYMBOLS_COUNT ) {
00063       console_printf ( "Overflow %s '%s'\n", "MAX_SYMBOLS_COUNT", str );
00064       return -1;
00065     }
00066     int len = strlen(str);
00067     if( len == 0 ) return -1;
00068     len++;
00069     if( len > (MAX_SYMBOLS_SIZE - (sym_table_pos - sym_table)) ) {
00070       console_printf ( "Overflow %s '%s'\n", "MAX_SYMBOLS_SIZE", str );
00071       return -1;
00072     }
00073 
00074     // ok! go.
00075     sym_index[sym_index_pos].hash = calc_hash (str);
00076     sym_index[sym_index_pos].pos = sym_table_pos;
00077     sym_id = sym_index_pos;
00078     sym_index_pos++;
00079     memcpy(sym_table_pos, str, len);
00080     sym_table_pos += len;
00081   }
00082 
00083   return sym_id;
00084 }
00085 
00086 
00087 //================================================================
00088 /*! Convert string to symbol value.
00089 
00090   @param  str       Target string.
00091   @return mrb_sym   Symbol value.
00092 */
00093 mrb_sym str_to_symid (const char *str)
00094 {
00095   uint16_t h = calc_hash (str);
00096   int i;
00097 
00098   for( i = 0; i < sym_index_pos; i++ ) {
00099     if( sym_index[i].hash == h ) {
00100       if( strcmp(str, sym_index[i].pos) == 0 ) {
00101         return i;
00102       }
00103     }
00104   }
00105   return -1;
00106 }
00107 
00108 
00109 //================================================================
00110 /*! Convert symbol value to string.
00111 
00112   @param  mrb_sym   Symbol value.
00113   @return const char*   String.
00114   @retval NULL      Invalid sym_id was given.
00115 */
00116 const char* symid_to_str (mrb_sym sym_id)
00117 {
00118   if( sym_id < 0 ) return NULL;
00119   if( sym_id >= sym_index_pos ) return NULL;
00120 
00121   return sym_index[sym_id].pos;
00122 }
00123