2013-10-10 04:22:25 -04:00
|
|
|
#include <string.h>
|
2013-10-13 03:01:40 -04:00
|
|
|
#include <stdlib.h>
|
2013-10-10 04:22:25 -04:00
|
|
|
|
|
|
|
#include "picrin.h"
|
2013-10-20 01:05:35 -04:00
|
|
|
#include "picrin/pair.h"
|
|
|
|
#include "picrin/symbol.h"
|
|
|
|
|
|
|
|
static int
|
|
|
|
str_hash(const char *str)
|
|
|
|
{
|
|
|
|
int hash = 0, len, i;
|
|
|
|
|
|
|
|
len = strlen(str);
|
|
|
|
for (i = 0; i < len; ++i) {
|
|
|
|
hash = hash * 31 + str[i];
|
|
|
|
}
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
2013-10-10 04:22:25 -04:00
|
|
|
pic_value
|
2013-10-20 01:05:35 -04:00
|
|
|
sym_tbl_get(struct sym_tbl *s_tbl, const char *key)
|
2013-10-10 04:22:25 -04:00
|
|
|
{
|
2013-10-20 01:05:35 -04:00
|
|
|
int hash, idx;
|
|
|
|
pic_value v, k;
|
|
|
|
char *name;
|
|
|
|
|
|
|
|
hash = str_hash(key);
|
|
|
|
idx = hash % s_tbl->size;
|
|
|
|
for (v = s_tbl->tbl[idx]; ! pic_nil_p(v); v = pic_pair_ptr(v)->cdr) {
|
|
|
|
k = pic_pair_ptr(v)->car;
|
|
|
|
|
|
|
|
name = pic_symbol_ptr(k)->name;
|
|
|
|
if (strcmp(name, key) == 0) {
|
|
|
|
return k;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return pic_undef_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_intern_cstr(pic_state *pic, const char *str)
|
|
|
|
{
|
|
|
|
pic_value v;
|
|
|
|
int len, hash, idx;
|
|
|
|
char *new_str;
|
2013-10-10 04:22:25 -04:00
|
|
|
struct pic_symbol *sym;
|
|
|
|
|
2013-10-20 01:05:35 -04:00
|
|
|
v = sym_tbl_get(pic->sym_tbl, str);
|
|
|
|
if (! pic_undef_p(v)) {
|
|
|
|
return v;
|
|
|
|
}
|
2013-10-10 04:22:25 -04:00
|
|
|
|
|
|
|
/* clone name string */
|
2013-10-20 01:05:35 -04:00
|
|
|
len = strlen(str);
|
|
|
|
new_str = (char *)pic_alloc(pic, len + 1);
|
|
|
|
strncpy(new_str, str, len + 1);
|
|
|
|
|
|
|
|
sym = (struct pic_symbol*)pic_obj_alloc(pic, sizeof(struct pic_symbol), PIC_TT_SYMBOL);
|
|
|
|
sym->name = new_str;
|
|
|
|
v = pic_obj_value(sym);
|
2013-10-10 04:22:25 -04:00
|
|
|
|
2013-10-20 01:05:35 -04:00
|
|
|
hash = str_hash(str);
|
|
|
|
idx = hash % pic->sym_tbl->size;
|
|
|
|
pic->sym_tbl->tbl[idx] = pic_cons(pic, v, pic->sym_tbl->tbl[idx]);
|
|
|
|
return v;
|
2013-10-10 04:22:25 -04:00
|
|
|
}
|