add pic_dict_next

This commit is contained in:
Yuichi Nishiwaki 2016-02-19 00:39:13 +09:00
parent aa2121b61c
commit 387ba469c8
6 changed files with 46 additions and 31 deletions

View File

@ -66,6 +66,23 @@ pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_sym *key)
kh_del(dict, h, it); 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 static pic_value
pic_dict_make_dictionary(pic_state *pic) pic_dict_make_dictionary(pic_state *pic)
{ {
@ -198,15 +215,14 @@ static pic_value
pic_dict_dictionary_to_alist(pic_state *pic) pic_dict_dictionary_to_alist(pic_state *pic)
{ {
struct pic_dict *dict; struct pic_dict *dict;
pic_value item, alist = pic_nil_value(pic); pic_value val, alist = pic_nil_value(pic);
pic_sym *sym; pic_sym *sym;
khiter_t it; int it = 0;
pic_get_args(pic, "d", &dict); pic_get_args(pic, "d", &dict);
pic_dict_for_each (sym, dict, it) { while (pic_dict_next(pic, dict, &it, &sym, &val)) {
item = pic_cons(pic, pic_obj_value(sym), pic_dict_ref(pic, dict, sym)); pic_push(pic, pic_cons(pic, pic_obj_value(sym), val), alist);
pic_push(pic, item, alist);
} }
return alist; return alist;
@ -234,14 +250,14 @@ static pic_value
pic_dict_dictionary_to_plist(pic_state *pic) pic_dict_dictionary_to_plist(pic_state *pic)
{ {
struct pic_dict *dict; struct pic_dict *dict;
pic_value plist = pic_nil_value(pic); pic_value val, plist = pic_nil_value(pic);
pic_sym *sym; pic_sym *sym;
khiter_t it; int it = 0;
pic_get_args(pic, "d", &dict); pic_get_args(pic, "d", &dict);
pic_dict_for_each (sym, dict, it) { while (pic_dict_next(pic, dict, &it, &sym, &val)) {
pic_push(pic, pic_dict_ref(pic, dict, sym), plist); pic_push(pic, val, plist);
pic_push(pic, pic_obj_value(sym), plist); pic_push(pic, pic_obj_value(sym), plist);
} }

View File

@ -360,11 +360,12 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
} }
case PIC_TYPE_DICT: { case PIC_TYPE_DICT: {
pic_sym *sym; 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_object(pic, (struct pic_object *)sym);
gc_mark(pic, pic_dict_ref(pic, &obj->u.dict, sym)); gc_mark(pic, val);
} }
break; break;
} }

View File

@ -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 *); void pic_dict_del(pic_state *, struct pic_dict *, pic_sym *);
bool pic_dict_has(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 *); 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 */ /* ephemeron */
struct pic_weak *pic_make_weak(pic_state *); struct pic_weak *pic_make_weak(pic_state *);

View File

@ -18,12 +18,6 @@ struct pic_dict {
#define pic_dict_ptr(v) ((struct pic_dict *)pic_obj_ptr(v)) #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) #if defined(__cplusplus)
} }
#endif #endif

View File

@ -107,13 +107,14 @@ void
pic_import(pic_state *pic, const char *lib) pic_import(pic_state *pic, const char *lib)
{ {
pic_sym *name, *realname, *uid; pic_sym *name, *realname, *uid;
khiter_t it; int it = 0;
pic_value val;
struct pic_lib *libp; struct pic_lib *libp;
libp = get_library(pic, lib); libp = get_library(pic, lib);
pic_dict_for_each (name, libp->exports, it) { while (pic_dict_next(pic, libp->exports, &it, &name, &val)) {
realname = pic_sym_ptr(pic_dict_ref(pic, libp->exports, name)); realname = pic_sym_ptr(val);
if ((uid = pic_find_identifier(pic, (pic_id *)realname, libp->env)) == NULL) { 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)); 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; const char *lib;
pic_value exports = pic_nil_value(pic); pic_value exports = pic_nil_value(pic);
pic_sym *sym; pic_sym *sym;
khiter_t it; int it = 0;
struct pic_lib *libp; struct pic_lib *libp;
pic_get_args(pic, "z", &lib); pic_get_args(pic, "z", &lib);
libp = get_library(pic, 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); pic_push(pic, pic_obj_value(sym), exports);
} }

View File

@ -242,13 +242,14 @@ write_dict(struct writer_control *p, struct pic_dict *dict)
{ {
pic_state *pic = p->pic; pic_state *pic = p->pic;
xFILE *file = p->file; xFILE *file = p->file;
pic_sym *sym; pic_sym *key;
khiter_t it; pic_value val;
int it = 0;
xfprintf(pic, file, "#.(dictionary"); xfprintf(pic, file, "#.(dictionary");
pic_dict_for_each (sym, dict, it) { while (pic_dict_next(pic, dict, &it, &key, &val)) {
xfprintf(pic, file, " '%s ", pic_str(pic, pic_sym_name(pic, sym))); xfprintf(pic, file, " '%s ", pic_str(pic, pic_sym_name(pic, key)));
write_core(p, pic_dict_ref(pic, dict, sym)); write_core(p, val);
} }
xfprintf(pic, file, ")"); xfprintf(pic, file, ")");
} }
@ -366,9 +367,10 @@ traverse(struct writer_control *p, pic_value obj)
} }
} else { } else {
/* dictionary */ /* dictionary */
pic_sym *sym; int it = 0;
pic_dict_for_each (sym, pic_dict_ptr(obj), it) { pic_value val;
traverse(p, pic_dict_ref(pic, pic_dict_ptr(obj), sym)); while (pic_dict_next(pic, pic_dict_ptr(obj), &it, NULL, &val)) {
traverse(p, val);
} }
} }