use khash for env

This commit is contained in:
Yuichi Nishiwaki 2015-06-25 07:26:48 +09:00
parent d500dd5d76
commit 5cbb44d6b8
4 changed files with 27 additions and 14 deletions

View File

@ -11,13 +11,14 @@
static pic_sym * static pic_sym *
lookup(pic_state PIC_UNUSED(*pic), pic_value var, struct pic_env *env) lookup(pic_state PIC_UNUSED(*pic), pic_value var, struct pic_env *env)
{ {
xh_entry *e; khiter_t it;
assert(pic_var_p(var)); assert(pic_var_p(var));
while (env != NULL) { while (env != NULL) {
if ((e = xh_get_ptr(&env->map, pic_ptr(var))) != NULL) { it = kh_get(env, &env->map, pic_ptr(var));
return xh_val(e, pic_sym *); if (it != kh_end(&env->map)) {
return kh_val(&env->map, it);
} }
env = env->up; env = env->up;
} }

View File

@ -405,14 +405,17 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
} }
case PIC_TT_ENV: { case PIC_TT_ENV: {
struct pic_env *env = (struct pic_env *)obj; struct pic_env *env = (struct pic_env *)obj;
xh_entry *it; khash_t(env) *h = &env->map;
khiter_t it;
if (env->up) { if (env->up) {
gc_mark_object(pic, (struct pic_object *)env->up); gc_mark_object(pic, (struct pic_object *)env->up);
} }
for (it = xh_begin(&env->map); it != NULL; it = xh_next(it)) { for (it = kh_begin(h); it != kh_end(h); ++it) {
gc_mark_object(pic, xh_key(it, struct pic_object *)); if (kh_exist(h, it)) {
gc_mark_object(pic, xh_val(it, struct pic_object *)); gc_mark_object(pic, kh_key(h, it));
gc_mark_object(pic, (struct pic_object *)kh_val(h, it));
}
} }
break; break;
} }
@ -688,7 +691,7 @@ gc_finalize_object(pic_state *pic, struct pic_object *obj)
} }
case PIC_TT_ENV: { case PIC_TT_ENV: {
struct pic_env *env = (struct pic_env *)obj; struct pic_env *env = (struct pic_env *)obj;
xh_destroy(&env->map); kh_destroy(env, &env->map);
break; break;
} }
case PIC_TT_LIB: { case PIC_TT_LIB: {

View File

@ -9,6 +9,8 @@
extern "C" { extern "C" {
#endif #endif
KHASH_DECLARE(env, void *, pic_sym *)
struct pic_id { struct pic_id {
PIC_OBJECT_HEADER PIC_OBJECT_HEADER
pic_value var; pic_value var;
@ -17,7 +19,7 @@ struct pic_id {
struct pic_env { struct pic_env {
PIC_OBJECT_HEADER PIC_OBJECT_HEADER
xhash map; khash_t(env) map;
struct pic_env *up; struct pic_env *up;
}; };

View File

@ -4,6 +4,8 @@
#include "picrin.h" #include "picrin.h"
KHASH_DEFINE(env, void *, pic_sym *, kh_ptr_hash_func, kh_ptr_hash_equal)
bool bool
pic_var_p(pic_value obj) pic_var_p(pic_value obj)
{ {
@ -30,7 +32,7 @@ pic_make_env(pic_state *pic, struct pic_env *up)
env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV); env = (struct pic_env *)pic_obj_alloc(pic, sizeof(struct pic_env), PIC_TT_ENV);
env->up = up; env->up = up;
xh_init_ptr(&env->map, sizeof(pic_sym *)); kh_init(env, &env->map);
return env; return env;
} }
@ -74,22 +76,27 @@ pic_add_variable(pic_state *pic, struct pic_env *env, pic_value var)
void void
pic_put_variable(pic_state PIC_UNUSED(*pic), struct pic_env *env, pic_value var, pic_sym *uid) pic_put_variable(pic_state PIC_UNUSED(*pic), struct pic_env *env, pic_value var, pic_sym *uid)
{ {
khiter_t it;
int ret;
assert(pic_var_p(var)); assert(pic_var_p(var));
xh_put_ptr(&env->map, pic_ptr(var), &uid); it = kh_put(env, &env->map, pic_ptr(var), &ret);
kh_val(&env->map, it) = uid;
} }
pic_sym * pic_sym *
pic_find_variable(pic_state PIC_UNUSED(*pic), struct pic_env *env, pic_value var) pic_find_variable(pic_state PIC_UNUSED(*pic), struct pic_env *env, pic_value var)
{ {
xh_entry *e; khiter_t it;
assert(pic_var_p(var)); assert(pic_var_p(var));
if ((e = xh_get_ptr(&env->map, pic_ptr(var))) == NULL) { it = kh_get(env, &env->map, pic_ptr(var));
if (it == kh_end(&env->map)) {
return NULL; return NULL;
} }
return xh_val(e, pic_sym *); return kh_val(&env->map, it);
} }
static pic_value static pic_value