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);
}
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);
}

View File

@ -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;
}

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 *);
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 *);

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}
}