diff --git a/extlib/benz/eval.c b/extlib/benz/eval.c index eaf6a72a..248b67f9 100644 --- a/extlib/benz/eval.c +++ b/extlib/benz/eval.c @@ -147,13 +147,13 @@ define_var(pic_state *pic, analyze_scope *scope, pic_sym *sym) int ret; if (search_scope(pic, scope, sym)) { - if (scope->depth > 0 || pic_weak_has(pic, pic->globals, sym)) { + if (scope->depth > 0 || pic_weak_has(pic, pic->globals, pic_obj_value(sym))) { pic_warnf(pic, "redefining variable: ~s", pic_obj_value(sym)); } return; } - pic_weak_set(pic, pic->globals, sym, pic_invalid_value()); + pic_weak_set(pic, pic->globals, pic_obj_value(sym), pic_invalid_value()); kh_put(a, &scope->locals, sym, &ret); } diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 8baa2239..b903f048 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -471,14 +471,10 @@ gc_mark_phase(pic_state *pic) M(sADD); M(sSUB); M(sMUL); M(sDIV); M(sEQ); M(sLT); M(sLE); M(sGT); M(sGE); M(sNOT); /* global variables */ - if (pic->globals) { - gc_mark_object(pic, (struct pic_object *)pic->globals); - } + gc_mark(pic, pic->globals); /* macro objects */ - if (pic->macros) { - gc_mark_object(pic, (struct pic_object *)pic->macros); - } + gc_mark(pic, pic->macros); /* error object */ gc_mark(pic, pic->err); diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index 20934ef8..2b092037 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -242,11 +242,11 @@ int pic_dict_size(pic_state *, pic_value dict); bool pic_dict_next(pic_state *, pic_value dict, int *iter, pic_sym **key, pic_value *val); /* ephemeron */ -struct pic_weak *pic_make_weak(pic_state *); -pic_value pic_weak_ref(pic_state *, struct pic_weak *, void *); -void pic_weak_set(pic_state *, struct pic_weak *, void *, pic_value); -void pic_weak_del(pic_state *, struct pic_weak *, void *); -bool pic_weak_has(pic_state *, struct pic_weak *, void *); +pic_value pic_make_weak(pic_state *); +pic_value pic_weak_ref(pic_state *, pic_value weak, pic_value key); +void pic_weak_set(pic_state *, pic_value weak, pic_value key, pic_value val); +void pic_weak_del(pic_state *, pic_value weak, pic_value key); +bool pic_weak_has(pic_state *, pic_value weak, pic_value key); /* symbol */ pic_sym *pic_intern(pic_state *, pic_value str); diff --git a/extlib/benz/include/picrin/object.h b/extlib/benz/include/picrin/object.h index 22953098..cbe3e264 100644 --- a/extlib/benz/include/picrin/object.h +++ b/extlib/benz/include/picrin/object.h @@ -11,7 +11,7 @@ extern "C" { KHASH_DECLARE(env, pic_id *, pic_sym *) KHASH_DECLARE(dict, pic_sym *, pic_value) -KHASH_DECLARE(weak, void *, pic_value) +KHASH_DECLARE(weak, struct pic_object *, pic_value) struct pic_id { union { @@ -125,11 +125,11 @@ struct pic_port { #define pic_pair_ptr(pic, o) ((struct pic_pair *)pic_obj_ptr(o)) #define pic_vec_ptr(pic, o) ((struct pic_vector *)pic_obj_ptr(o)) #define pic_dict_ptr(pic, o) ((struct pic_dict *)pic_obj_ptr(o)) +#define pic_weak_ptr(pic, o) ((struct pic_weak *)pic_obj_ptr(o)) #define pic_data_ptr(pic, o) ((struct pic_data *)pic_obj_ptr(o)) #define pic_proc_ptr(pic, o) ((struct pic_proc *)pic_obj_ptr(o)) #define pic_sym_ptr(v) ((pic_sym *)pic_obj_ptr(v)) #define pic_id_ptr(v) ((pic_id *)pic_obj_ptr(v)) -#define pic_weak_ptr(v) ((struct pic_weak *)pic_obj_ptr(v)) #define pic_context_ptr(o) ((struct pic_context *)pic_obj_ptr(o)) #define pic_rec_ptr(v) ((struct pic_record *)pic_obj_ptr(v)) #define pic_error_ptr(v) ((struct pic_error *)pic_obj_ptr(v)) diff --git a/extlib/benz/include/picrin/state.h b/extlib/benz/include/picrin/state.h index c5590788..30220021 100644 --- a/extlib/benz/include/picrin/state.h +++ b/extlib/benz/include/picrin/state.h @@ -79,8 +79,8 @@ struct pic_state { khash_t(oblist) oblist; /* string to symbol */ int ucnt; - struct pic_weak *globals; - struct pic_weak *macros; + pic_value globals; /* weak */ + pic_value macros; /* weak */ khash_t(ltable) ltable; struct pic_list ireps; /* chain */ diff --git a/extlib/benz/macro.c b/extlib/benz/macro.c index 436df18f..486362a1 100644 --- a/extlib/benz/macro.c +++ b/extlib/benz/macro.c @@ -109,26 +109,26 @@ pic_find_identifier(pic_state *pic, pic_id *id, struct pic_env *env) static void define_macro(pic_state *pic, pic_sym *uid, pic_value mac) { - if (pic_weak_has(pic, pic->macros, uid)) { + if (pic_weak_has(pic, pic->macros, pic_obj_value(uid))) { pic_warnf(pic, "redefining syntax variable: ~s", pic_obj_value(uid)); } - pic_weak_set(pic, pic->macros, uid, mac); + pic_weak_set(pic, pic->macros, pic_obj_value(uid), mac); } static pic_value find_macro(pic_state *pic, pic_sym *uid) { - if (! pic_weak_has(pic, pic->macros, uid)) { + if (! pic_weak_has(pic, pic->macros, pic_obj_value(uid))) { return pic_false_value(pic); } - return pic_weak_ref(pic, pic->macros, uid); + return pic_weak_ref(pic, pic->macros, pic_obj_value(uid)); } static void shadow_macro(pic_state *pic, pic_sym *uid) { - if (pic_weak_has(pic, pic->macros, uid)) { - pic_weak_del(pic, pic->macros, uid); + if (pic_weak_has(pic, pic->macros, pic_obj_value(uid))) { + pic_weak_del(pic, pic->macros, pic_obj_value(uid)); } } diff --git a/extlib/benz/proc.c b/extlib/benz/proc.c index aa7a4ee0..69d7d34d 100644 --- a/extlib/benz/proc.c +++ b/extlib/benz/proc.c @@ -182,16 +182,16 @@ pic_get_args(pic_state *pic, const char *format, ...) static pic_value vm_gref(pic_state *pic, pic_sym *uid) { - if (! pic_weak_has(pic, pic->globals, uid)) { + if (! pic_weak_has(pic, pic->globals, pic_obj_value(uid))) { pic_errorf(pic, "uninitialized global variable: %s", pic_str(pic, pic_sym_name(pic, uid))); } - return pic_weak_ref(pic, pic->globals, uid); + return pic_weak_ref(pic, pic->globals, pic_obj_value(uid)); } static void vm_gset(pic_state *pic, pic_sym *uid, pic_value value) { - pic_weak_set(pic, pic->globals, uid, value); + pic_weak_set(pic, pic->globals, pic_obj_value(uid), value); } static void @@ -896,7 +896,7 @@ pic_define(pic_state *pic, const char *lib, const char *name, pic_value val) if ((uid = pic_find_identifier(pic, (pic_id *)sym, env)) == NULL) { uid = pic_add_identifier(pic, (pic_id *)sym, env); } else { - if (pic_weak_has(pic, pic->globals, uid)) { + if (pic_weak_has(pic, pic->globals, pic_obj_value(uid))) { pic_warnf(pic, "redefining variable: ~s", pic_obj_value(uid)); } } diff --git a/extlib/benz/state.c b/extlib/benz/state.c index 77763c6a..60ed6d9a 100644 --- a/extlib/benz/state.c +++ b/extlib/benz/state.c @@ -259,10 +259,10 @@ pic_open(pic_allocf allocf, void *userdata) pic->ucnt = 0; /* global variables */ - pic->globals = NULL; + pic->globals = pic_make_weak(pic); /* macros */ - pic->macros = NULL; + pic->macros = pic_make_weak(pic); /* features */ pic->features = pic_nil_value(pic); @@ -354,7 +354,7 @@ pic_open(pic_allocf allocf, void *userdata) pic_reader_init(pic); /* parameter table */ - pic->ptable = pic_cons(pic, pic_obj_value(pic_make_weak(pic)), pic->ptable); + pic->ptable = pic_cons(pic, pic_make_weak(pic), pic->ptable); /* standard libraries */ pic_make_library(pic, "picrin.user"); @@ -394,8 +394,8 @@ pic_close(pic_state *pic) pic->xp = pic->xpbase; pic->arena_idx = 0; pic->err = pic_invalid_value(); - pic->globals = NULL; - pic->macros = NULL; + pic->globals = pic_invalid_value(); + pic->macros = pic_invalid_value(); pic->features = pic_nil_value(pic); /* free all libraries */ diff --git a/extlib/benz/var.c b/extlib/benz/var.c index 04a07e5e..6f59c0c7 100644 --- a/extlib/benz/var.c +++ b/extlib/benz/var.c @@ -8,13 +8,11 @@ static pic_value var_get(pic_state *pic, pic_value var) { - pic_value elem, it; - struct pic_weak *weak; + pic_value weak, it; - pic_for_each (elem, pic->ptable, it) { - weak = pic_weak_ptr(elem); - if (pic_weak_has(pic, weak, pic_obj_ptr(var))) { - return pic_weak_ref(pic, weak, pic_obj_ptr(var)); + pic_for_each (weak, pic->ptable, it) { + if (pic_weak_has(pic, weak, var)) { + return pic_weak_ref(pic, weak, var); } } pic_panic(pic, "logic flaw"); @@ -23,11 +21,11 @@ var_get(pic_state *pic, pic_value var) static pic_value var_set(pic_state *pic, pic_value var, pic_value val) { - struct pic_weak *weak; + pic_value weak; - weak = pic_weak_ptr(pic_car(pic, pic->ptable)); + weak = pic_car(pic, pic->ptable); - pic_weak_set(pic, weak, pic_obj_ptr(var), val); + pic_weak_set(pic, weak, var, val); return pic_undef_value(pic); } @@ -82,7 +80,7 @@ pic_var_with_parameter(pic_state *pic) pic_get_args(pic, "l", &body); - pic->ptable = pic_cons(pic, pic_obj_value(pic_make_weak(pic)), pic->ptable); + pic->ptable = pic_cons(pic, pic_make_weak(pic), pic->ptable); val = pic_call(pic, body, 0); diff --git a/extlib/benz/weak.c b/extlib/benz/weak.c index 69effdcc..1ba978b1 100644 --- a/extlib/benz/weak.c +++ b/extlib/benz/weak.c @@ -5,9 +5,9 @@ #include "picrin.h" #include "picrin/object.h" -KHASH_DEFINE(weak, void *, pic_value, kh_ptr_hash_func, kh_ptr_hash_equal) +KHASH_DEFINE(weak, struct pic_object *, pic_value, kh_ptr_hash_func, kh_ptr_hash_equal) -struct pic_weak * +pic_value pic_make_weak(pic_state *pic) { struct pic_weak *weak; @@ -16,97 +16,59 @@ pic_make_weak(pic_state *pic) weak->prev = NULL; kh_init(weak, &weak->hash); - return weak; + return pic_obj_value(weak); } pic_value -pic_weak_ref(pic_state *pic, struct pic_weak *weak, void *key) +pic_weak_ref(pic_state *pic, pic_value weak, pic_value key) { - khash_t(weak) *h = &weak->hash; + khash_t(weak) *h = &pic_weak_ptr(pic, weak)->hash; khiter_t it; - it = kh_get(weak, h, key); + it = kh_get(weak, h, pic_obj_ptr(key)); if (it == kh_end(h)) { - pic_errorf(pic, "element not found for a key: ~s", pic_obj_value(key)); + pic_errorf(pic, "element not found for a key: ~s", key); } return kh_val(h, it); } -void * -pic_weak_rev_ref(pic_state *pic, struct pic_weak *weak, pic_value val) -{ - khash_t(weak) *h = &weak->hash; - - if (h->n_buckets) { - khint_t i = 0; - while ((i < h->n_buckets) && (ac_iseither(h->flags, i) || !pic_eq_p(pic, h->vals[i], val))) { - i += 1; - } - if (i < h->n_buckets) return kh_key(h, i); - } - pic_errorf(pic, "key not found for an element: ~s", val); - return NULL; -} - void -pic_weak_set(pic_state PIC_UNUSED(*pic), struct pic_weak *weak, void *key, pic_value val) +pic_weak_set(pic_state *pic, pic_value weak, pic_value key, pic_value val) { - khash_t(weak) *h = &weak->hash; + khash_t(weak) *h = &pic_weak_ptr(pic, weak)->hash; int ret; khiter_t it; - it = kh_put(weak, h, key, &ret); + it = kh_put(weak, h, pic_obj_ptr(key), &ret); kh_val(h, it) = val; } bool -pic_weak_has(pic_state PIC_UNUSED(*pic), struct pic_weak *weak, void *key) +pic_weak_has(pic_state *pic, pic_value weak, pic_value key) { - return kh_get(weak, &weak->hash, key) != kh_end(&weak->hash); + khash_t(weak) *h = &pic_weak_ptr(pic, weak)->hash; + + return kh_get(weak, h, pic_obj_ptr(key)) != kh_end(h); } void -pic_weak_del(pic_state *pic, struct pic_weak *weak, void *key) +pic_weak_del(pic_state *pic, pic_value weak, pic_value key) { - khash_t(weak) *h = &weak->hash; + khash_t(weak) *h = &pic_weak_ptr(pic, weak)->hash; khiter_t it; - it = kh_get(weak, h, key); + it = kh_get(weak, h, pic_obj_ptr(key)); if (it == kh_end(h)) { - pic_errorf(pic, "no slot named ~s found in ephemeron", pic_obj_value(key)); + pic_errorf(pic, "no slot named ~s found in ephemeron", key); } kh_del(weak, h, it); } -static pic_value -weak_get(pic_state *pic, struct pic_weak *weak, void *key) -{ - if (! pic_weak_has(pic, weak, key)) { - return pic_false_value(pic); - } - return pic_cons(pic, pic_obj_value(key), pic_weak_ref(pic, weak, key)); -} - -static pic_value -weak_set(pic_state *pic, struct pic_weak *weak, void *key, pic_value val) -{ - if (pic_undef_p(pic, val)) { - if (pic_weak_has(pic, weak, key)) { - pic_weak_del(pic, weak, key); - } - } else { - pic_weak_set(pic, weak, key, val); - } - - return pic_undef_value(pic); -} - static pic_value weak_call(pic_state *pic) { - struct pic_weak *weak; - pic_value key, val; + pic_value key, val, weak; int n; n = pic_get_args(pic, "o|o", &key, &val); @@ -115,12 +77,22 @@ weak_call(pic_state *pic) pic_errorf(pic, "attempted to set a non-object key '~s' in an ephemeron", key); } - weak = pic_weak_ptr(pic_closure_ref(pic, 0)); + weak = pic_closure_ref(pic, 0); if (n == 1) { - return weak_get(pic, weak, pic_obj_ptr(key)); + if (! pic_weak_has(pic, weak, key)) { + return pic_false_value(pic); + } + return pic_cons(pic, key, pic_weak_ref(pic, weak, key)); } else { - return weak_set(pic, weak, pic_obj_ptr(key), val); + if (pic_undef_p(pic, val)) { + if (pic_weak_has(pic, weak, key)) { + pic_weak_del(pic, weak, key); + } + } else { + pic_weak_set(pic, weak, key, val); + } + return pic_undef_value(pic); } } @@ -129,7 +101,7 @@ pic_weak_make_ephemeron(pic_state *pic) { pic_get_args(pic, ""); - return pic_lambda(pic, weak_call, 1, pic_obj_value(pic_make_weak(pic))); + return pic_lambda(pic, weak_call, 1, pic_make_weak(pic)); } void