intern symbols using hash table

This commit is contained in:
Yuichi Nishiwaki
2013-10-20 14:05:48 +09:00
parent bde09e063a
commit 7322271d65
5 changed files with 90 additions and 10 deletions
+6 -2
View File
@@ -3,9 +3,10 @@
#include "picrin.h"
#include "picrin/gc.h"
#include "picrin/proc.h"
#include "picrin/symbol.h"
static struct pic_env *
pic_new_empty_env()
new_empty_env()
{
struct pic_env *env;
@@ -37,6 +38,9 @@ pic_open()
pic->heap = (struct heap_page *)malloc(sizeof(struct heap_page));
init_heap_page(pic->heap);
/* symbol table */
pic->sym_tbl = sym_tbl_new();
/* irep */
pic->irep = (struct pic_irep **)malloc(sizeof(struct pic_irep *) * PIC_IREP_SIZE);
pic->ilen = 0;
@@ -64,7 +68,7 @@ pic_open()
pic->sDIV = pic_intern_cstr(pic, "/");
/* global environment */
pic->global_env = pic_new_empty_env();
pic->global_env = new_empty_env();
pic_init_core(pic);
return pic;
+69 -8
View File
@@ -2,19 +2,80 @@
#include <stdlib.h>
#include "picrin.h"
#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;
}
struct sym_tbl *
sym_tbl_new()
{
struct sym_tbl *s_tbl;
int i;
s_tbl = (struct sym_tbl *)malloc(sizeof(struct sym_tbl));
s_tbl->size = PIC_SYM_TBL_SIZE;
for (i = 0; i < PIC_SYM_TBL_SIZE; ++i) {
s_tbl->tbl[i] = pic_nil_value();
}
return s_tbl;
}
pic_value
pic_intern_cstr(pic_state *pic, const char *name)
sym_tbl_get(struct sym_tbl *s_tbl, const char *key)
{
struct pic_symbol *sym;
size_t len;
int hash, idx;
pic_value v, k;
char *name;
sym = (struct pic_symbol*)pic_obj_alloc(pic, sizeof(struct pic_symbol), PIC_TT_SYMBOL);
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;
struct pic_symbol *sym;
v = sym_tbl_get(pic->sym_tbl, str);
if (! pic_undef_p(v)) {
return v;
}
/* clone name string */
len = strlen(name);
sym->name = (char *)pic_alloc(pic, len + 1);
strncpy(sym->name, name, len + 1);
len = strlen(str);
new_str = (char *)pic_alloc(pic, len + 1);
strncpy(new_str, str, len + 1);
return pic_obj_value(sym);
sym = (struct pic_symbol*)pic_obj_alloc(pic, sizeof(struct pic_symbol), PIC_TT_SYMBOL);
sym->name = new_str;
v = pic_obj_value(sym);
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;
}