diff --git a/extlib/benz/dict.c b/extlib/benz/dict.c index 39dcacf6..80aed488 100644 --- a/extlib/benz/dict.c +++ b/extlib/benz/dict.c @@ -66,6 +66,23 @@ pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_sym *key) kh_del(dict, h, it); } +bool +pic_dict_next(pic_state PIC_UNUSED(*pic), struct pic_dict *dict, int *iter, pic_sym **key, pic_value *val) +{ + khash_t(dict) *h = &dict->hash; + int it = *iter; + + for (it = *iter; it != kh_end(h); ++it) { + if (kh_exist(h, it)) { + if (key) *key = kh_key(h, it); + if (val) *val = kh_val(h, it); + *iter = ++it; + return true; + } + } + return false; +} + static pic_value pic_dict_make_dictionary(pic_state *pic) { @@ -198,15 +215,14 @@ static pic_value pic_dict_dictionary_to_alist(pic_state *pic) { struct pic_dict *dict; - pic_value item, alist = pic_nil_value(pic); + pic_value val, alist = pic_nil_value(pic); pic_sym *sym; - khiter_t it; + int it = 0; pic_get_args(pic, "d", &dict); - pic_dict_for_each (sym, dict, it) { - item = pic_cons(pic, pic_obj_value(sym), pic_dict_ref(pic, dict, sym)); - pic_push(pic, item, alist); + while (pic_dict_next(pic, dict, &it, &sym, &val)) { + pic_push(pic, pic_cons(pic, pic_obj_value(sym), val), alist); } return alist; @@ -234,14 +250,14 @@ static pic_value pic_dict_dictionary_to_plist(pic_state *pic) { struct pic_dict *dict; - pic_value plist = pic_nil_value(pic); + pic_value val, plist = pic_nil_value(pic); pic_sym *sym; - khiter_t it; + int it = 0; pic_get_args(pic, "d", &dict); - pic_dict_for_each (sym, dict, it) { - pic_push(pic, pic_dict_ref(pic, dict, sym), plist); + while (pic_dict_next(pic, dict, &it, &sym, &val)) { + pic_push(pic, val, plist); pic_push(pic, pic_obj_value(sym), plist); } diff --git a/extlib/benz/gc.c b/extlib/benz/gc.c index 922968d5..cf32889d 100644 --- a/extlib/benz/gc.c +++ b/extlib/benz/gc.c @@ -360,11 +360,12 @@ gc_mark_object(pic_state *pic, struct pic_object *obj) } case PIC_TYPE_DICT: { pic_sym *sym; - khiter_t it; + pic_value val; + int it = 0; - pic_dict_for_each (sym, &obj->u.dict, it) { + while (pic_dict_next(pic, &obj->u.dict, &it, &sym, &val)) { gc_mark_object(pic, (struct pic_object *)sym); - gc_mark(pic, pic_dict_ref(pic, &obj->u.dict, sym)); + gc_mark(pic, val); } break; } diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index ab3c9796..177b877b 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -231,6 +231,7 @@ void pic_dict_set(pic_state *, struct pic_dict *, pic_sym *, pic_value); void pic_dict_del(pic_state *, struct pic_dict *, pic_sym *); bool pic_dict_has(pic_state *, struct pic_dict *, pic_sym *); int pic_dict_size(pic_state *, struct pic_dict *); +bool pic_dict_next(pic_state *, struct pic_dict *, int *iter, pic_sym **key, pic_value *val); /* ephemeron */ struct pic_weak *pic_make_weak(pic_state *); diff --git a/extlib/benz/include/picrin/dict.h b/extlib/benz/include/picrin/dict.h index d0ce786e..bcb3a427 100644 --- a/extlib/benz/include/picrin/dict.h +++ b/extlib/benz/include/picrin/dict.h @@ -18,12 +18,6 @@ struct pic_dict { #define pic_dict_ptr(v) ((struct pic_dict *)pic_obj_ptr(v)) -#define pic_dict_for_each(sym, dict, it) \ - pic_dict_for_each_help(sym, (&(dict)->hash), it) -#define pic_dict_for_each_help(sym, h, it) \ - for (it = kh_begin(h); it != kh_end(h); ++it) \ - if ((sym = kh_key(h, it)), kh_exist(h, it)) - #if defined(__cplusplus) } #endif diff --git a/extlib/benz/lib.c b/extlib/benz/lib.c index 311f6ed5..b0784941 100644 --- a/extlib/benz/lib.c +++ b/extlib/benz/lib.c @@ -107,13 +107,14 @@ void pic_import(pic_state *pic, const char *lib) { pic_sym *name, *realname, *uid; - khiter_t it; + int it = 0; + pic_value val; struct pic_lib *libp; libp = get_library(pic, lib); - pic_dict_for_each (name, libp->exports, it) { - realname = pic_sym_ptr(pic_dict_ref(pic, libp->exports, name)); + while (pic_dict_next(pic, libp->exports, &it, &name, &val)) { + realname = pic_sym_ptr(val); if ((uid = pic_find_identifier(pic, (pic_id *)realname, libp->env)) == NULL) { pic_errorf(pic, "attempted to export undefined variable '~s'", pic_obj_value(realname)); @@ -220,14 +221,14 @@ pic_lib_library_exports(pic_state *pic) const char *lib; pic_value exports = pic_nil_value(pic); pic_sym *sym; - khiter_t it; + int it = 0; struct pic_lib *libp; pic_get_args(pic, "z", &lib); libp = get_library(pic, lib); - pic_dict_for_each (sym, libp->exports, it) { + while (pic_dict_next(pic, libp->exports, &it, &sym, NULL)) { pic_push(pic, pic_obj_value(sym), exports); } diff --git a/extlib/benz/write.c b/extlib/benz/write.c index 9e3e2a50..6cf79c7e 100644 --- a/extlib/benz/write.c +++ b/extlib/benz/write.c @@ -242,13 +242,14 @@ write_dict(struct writer_control *p, struct pic_dict *dict) { pic_state *pic = p->pic; xFILE *file = p->file; - pic_sym *sym; - khiter_t it; + pic_sym *key; + pic_value val; + int it = 0; xfprintf(pic, file, "#.(dictionary"); - pic_dict_for_each (sym, dict, it) { - xfprintf(pic, file, " '%s ", pic_str(pic, pic_sym_name(pic, sym))); - write_core(p, pic_dict_ref(pic, dict, sym)); + while (pic_dict_next(pic, dict, &it, &key, &val)) { + xfprintf(pic, file, " '%s ", pic_str(pic, pic_sym_name(pic, key))); + write_core(p, val); } xfprintf(pic, file, ")"); } @@ -366,9 +367,10 @@ traverse(struct writer_control *p, pic_value obj) } } else { /* dictionary */ - pic_sym *sym; - pic_dict_for_each (sym, pic_dict_ptr(obj), it) { - traverse(p, pic_dict_ref(pic, pic_dict_ptr(obj), sym)); + int it = 0; + pic_value val; + while (pic_dict_next(pic, pic_dict_ptr(obj), &it, NULL, &val)) { + traverse(p, val); } }