2014-08-25 00:38:09 -04:00
|
|
|
/**
|
|
|
|
* See Copyright Notice in picrin.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "picrin.h"
|
|
|
|
#include "picrin/dict.h"
|
2014-08-30 13:39:09 -04:00
|
|
|
#include "picrin/cont.h"
|
2014-09-13 03:14:33 -04:00
|
|
|
#include "picrin/pair.h"
|
2014-08-25 00:38:09 -04:00
|
|
|
|
|
|
|
struct pic_dict *
|
2014-09-12 06:41:20 -04:00
|
|
|
pic_make_dict(pic_state *pic)
|
2014-08-25 00:38:09 -04:00
|
|
|
{
|
|
|
|
struct pic_dict *dict;
|
|
|
|
|
|
|
|
dict = (struct pic_dict *)pic_obj_alloc(pic, sizeof(struct pic_dict), PIC_TT_DICT);
|
|
|
|
xh_init_int(&dict->hash, sizeof(pic_value));
|
|
|
|
|
|
|
|
return dict;
|
|
|
|
}
|
|
|
|
|
|
|
|
pic_value
|
|
|
|
pic_dict_ref(pic_state *pic, struct pic_dict *dict, pic_sym key)
|
|
|
|
{
|
|
|
|
xh_entry *e;
|
|
|
|
|
|
|
|
e = xh_get_int(&dict->hash, key);
|
|
|
|
if (! e) {
|
|
|
|
pic_errorf(pic, "element not found for a key: ~s", pic_sym_value(key));
|
|
|
|
}
|
|
|
|
return xh_val(e, pic_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pic_dict_set(pic_state *pic, struct pic_dict *dict, pic_sym key, pic_value val)
|
|
|
|
{
|
|
|
|
UNUSED(pic);
|
|
|
|
|
|
|
|
xh_put_int(&dict->hash, key, &val);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
pic_dict_size(pic_state *pic, struct pic_dict *dict)
|
|
|
|
{
|
|
|
|
UNUSED(pic);
|
|
|
|
|
|
|
|
return dict->hash.count;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
pic_dict_has(pic_state *pic, struct pic_dict *dict, pic_sym key)
|
|
|
|
{
|
|
|
|
UNUSED(pic);
|
|
|
|
|
|
|
|
return xh_get_int(&dict->hash, key) != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_sym key)
|
|
|
|
{
|
|
|
|
if (xh_get_int(&dict->hash, key) == NULL) {
|
|
|
|
pic_errorf(pic, "no slot named ~s found in dictionary", pic_sym_value(key));
|
|
|
|
}
|
|
|
|
|
|
|
|
xh_del_int(&dict->hash, key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_dict_dict(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_dict *dict;
|
|
|
|
|
|
|
|
pic_get_args(pic, "");
|
|
|
|
|
2014-09-12 06:41:20 -04:00
|
|
|
dict = pic_make_dict(pic);
|
2014-08-25 00:38:09 -04:00
|
|
|
|
|
|
|
return pic_obj_value(dict);
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_p(pic_state *pic)
|
|
|
|
{
|
|
|
|
pic_value obj;
|
|
|
|
|
|
|
|
pic_get_args(pic, "o", &obj);
|
|
|
|
|
|
|
|
return pic_bool_value(pic_dict_p(obj));
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_ref(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_dict *dict;
|
|
|
|
pic_sym key;
|
|
|
|
|
|
|
|
pic_get_args(pic, "dm", &dict, &key);
|
|
|
|
|
2014-08-30 13:39:09 -04:00
|
|
|
if (pic_dict_has(pic, dict, key)) {
|
|
|
|
return pic_values2(pic, pic_dict_ref(pic, dict, key), pic_true_value());
|
|
|
|
} else {
|
|
|
|
return pic_values2(pic, pic_none_value(), pic_false_value());
|
|
|
|
}
|
2014-08-25 00:38:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_set(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_dict *dict;
|
|
|
|
pic_sym key;
|
|
|
|
pic_value val;
|
|
|
|
|
|
|
|
pic_get_args(pic, "dmo", &dict, &key, &val);
|
|
|
|
|
|
|
|
pic_dict_set(pic, dict, key, val);
|
|
|
|
|
|
|
|
return pic_none_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_del(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_dict *dict;
|
|
|
|
pic_sym key;
|
|
|
|
|
|
|
|
pic_get_args(pic, "dm", &dict, &key);
|
|
|
|
|
|
|
|
pic_dict_del(pic, dict, key);
|
|
|
|
|
|
|
|
return pic_none_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_size(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_dict *dict;
|
|
|
|
|
|
|
|
pic_get_args(pic, "d", &dict);
|
|
|
|
|
|
|
|
return pic_int_value(pic_dict_size(pic, dict));
|
|
|
|
}
|
|
|
|
|
2014-09-13 03:22:22 -04:00
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_map(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_proc *proc;
|
|
|
|
struct pic_dict *dict;
|
|
|
|
pic_value item, list = pic_nil_value();
|
|
|
|
xh_iter it;
|
|
|
|
|
|
|
|
pic_get_args(pic, "ld", &proc, &dict);
|
|
|
|
|
|
|
|
xh_begin(&it, &dict->hash);
|
|
|
|
while (xh_next(&it)) {
|
|
|
|
item = pic_cons(pic, pic_sym_value(xh_key(it.e, pic_sym)), xh_val(it.e, pic_value));
|
|
|
|
pic_push(pic, pic_apply1(pic, proc, item), list);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pic_reverse(pic, list);
|
|
|
|
}
|
|
|
|
|
2014-09-13 03:14:33 -04:00
|
|
|
static pic_value
|
|
|
|
pic_dict_dict_for_each(pic_state *pic)
|
|
|
|
{
|
|
|
|
struct pic_proc *proc;
|
|
|
|
struct pic_dict *dict;
|
|
|
|
pic_value item;
|
|
|
|
xh_iter it;
|
|
|
|
|
|
|
|
pic_get_args(pic, "ld", &proc, &dict);
|
|
|
|
|
|
|
|
xh_begin(&it, &dict->hash);
|
|
|
|
while (xh_next(&it)) {
|
|
|
|
int ai = pic_gc_arena_preserve(pic);
|
|
|
|
|
|
|
|
item = pic_cons(pic, pic_sym_value(xh_key(it.e, pic_sym)), xh_val(it.e, pic_value));
|
|
|
|
pic_apply1(pic, proc, item);
|
|
|
|
|
|
|
|
pic_gc_arena_restore(pic, ai);
|
|
|
|
}
|
|
|
|
|
|
|
|
return pic_none_value();
|
|
|
|
}
|
|
|
|
|
2014-08-25 00:38:09 -04:00
|
|
|
void
|
|
|
|
pic_init_dict(pic_state *pic)
|
|
|
|
{
|
2014-08-31 22:37:52 -04:00
|
|
|
pic_defun(pic, "make-dictionary", pic_dict_dict);
|
|
|
|
pic_defun(pic, "dictionary?", pic_dict_dict_p);
|
|
|
|
pic_defun(pic, "dictionary-ref", pic_dict_dict_ref);
|
|
|
|
pic_defun(pic, "dictionary-set!", pic_dict_dict_set);
|
|
|
|
pic_defun(pic, "dictionary-delete", pic_dict_dict_del);
|
|
|
|
pic_defun(pic, "dictionary-size", pic_dict_dict_size);
|
2014-09-13 03:22:22 -04:00
|
|
|
pic_defun(pic, "dictionary-map", pic_dict_dict_map);
|
2014-09-13 03:14:33 -04:00
|
|
|
pic_defun(pic, "dictionary-for-each", pic_dict_dict_for_each);
|
2014-08-25 00:38:09 -04:00
|
|
|
}
|