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 *
lookup(pic_state PIC_UNUSED(*pic), pic_value var, struct pic_env *env)
{
xh_entry *e;
khiter_t it;
assert(pic_var_p(var));
while (env != NULL) {
if ((e = xh_get_ptr(&env->map, pic_ptr(var))) != NULL) {
return xh_val(e, pic_sym *);
it = kh_get(env, &env->map, pic_ptr(var));
if (it != kh_end(&env->map)) {
return kh_val(&env->map, it);
}
env = env->up;
}

View File

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

View File

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

View File

@ -4,6 +4,8 @@
#include "picrin.h"
KHASH_DEFINE(env, void *, pic_sym *, kh_ptr_hash_func, kh_ptr_hash_equal)
bool
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->up = up;
xh_init_ptr(&env->map, sizeof(pic_sym *));
kh_init(env, &env->map);
return env;
}
@ -74,22 +76,27 @@ pic_add_variable(pic_state *pic, struct pic_env *env, pic_value var)
void
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));
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_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));
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 xh_val(e, pic_sym *);
return kh_val(&env->map, it);
}
static pic_value