dictionary is now a equal?-based hash table
This commit is contained in:
parent
f8ec4ea2e1
commit
48f0ec9095
115
dict.c
115
dict.c
|
@ -7,35 +7,96 @@
|
|||
#include "picrin/cont.h"
|
||||
#include "picrin/pair.h"
|
||||
|
||||
static int
|
||||
xh_value_hash(const void *key, void *data)
|
||||
{
|
||||
union { double f; int i; } u;
|
||||
pic_value val = *(pic_value *)key;
|
||||
int hash;
|
||||
|
||||
UNUSED(data);
|
||||
|
||||
switch (pic_vtype(val)) {
|
||||
default:
|
||||
hash = 0;
|
||||
break;
|
||||
case PIC_VTYPE_SYMBOL:
|
||||
hash = pic_sym(val);
|
||||
break;
|
||||
case PIC_VTYPE_FLOAT:
|
||||
u.f = pic_float(val);
|
||||
hash = u.i;
|
||||
break;
|
||||
case PIC_VTYPE_INT:
|
||||
hash = pic_int(val);
|
||||
break;
|
||||
case PIC_VTYPE_HEAP:
|
||||
hash = (int)pic_ptr(val);
|
||||
break;
|
||||
}
|
||||
|
||||
return hash + pic_vtype(val);
|
||||
}
|
||||
|
||||
static int
|
||||
xh_value_equal(const void *key1, const void *key2, void *pic)
|
||||
{
|
||||
return pic_equal_p(pic, *(pic_value *)key1, *(pic_value *)key2);
|
||||
}
|
||||
|
||||
static void
|
||||
xh_init_value(pic_state *pic, xhash *x)
|
||||
{
|
||||
xh_init_(x, sizeof(pic_value), sizeof(pic_value), xh_value_hash, xh_value_equal, pic);
|
||||
}
|
||||
|
||||
static inline xh_entry *
|
||||
xh_get_value(xhash *x, pic_value key)
|
||||
{
|
||||
return xh_get_(x, &key);
|
||||
}
|
||||
|
||||
static inline xh_entry *
|
||||
xh_put_value(xhash *x, pic_value key, void *val)
|
||||
{
|
||||
return xh_put_(x, &key, val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xh_del_value(xhash *x, pic_value key)
|
||||
{
|
||||
xh_del_(x, &key);
|
||||
}
|
||||
|
||||
struct pic_dict *
|
||||
pic_make_dict(pic_state *pic)
|
||||
{
|
||||
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));
|
||||
xh_init_value(pic, &dict->hash);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
pic_value
|
||||
pic_dict_ref(pic_state *pic, struct pic_dict *dict, pic_sym key)
|
||||
pic_dict_ref(pic_state *pic, struct pic_dict *dict, pic_value key)
|
||||
{
|
||||
xh_entry *e;
|
||||
|
||||
e = xh_get_int(&dict->hash, key);
|
||||
e = xh_get_value(&dict->hash, key);
|
||||
if (! e) {
|
||||
pic_errorf(pic, "element not found for a key: ~s", pic_sym_value(key));
|
||||
pic_errorf(pic, "element not found for a key: ~s", key);
|
||||
}
|
||||
return xh_val(e, pic_value);
|
||||
}
|
||||
|
||||
void
|
||||
pic_dict_set(pic_state *pic, struct pic_dict *dict, pic_sym key, pic_value val)
|
||||
pic_dict_set(pic_state *pic, struct pic_dict *dict, pic_value key, pic_value val)
|
||||
{
|
||||
UNUSED(pic);
|
||||
|
||||
xh_put_int(&dict->hash, key, &val);
|
||||
xh_put_value(&dict->hash, key, &val);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -47,21 +108,21 @@ pic_dict_size(pic_state *pic, struct pic_dict *dict)
|
|||
}
|
||||
|
||||
bool
|
||||
pic_dict_has(pic_state *pic, struct pic_dict *dict, pic_sym key)
|
||||
pic_dict_has(pic_state *pic, struct pic_dict *dict, pic_value key)
|
||||
{
|
||||
UNUSED(pic);
|
||||
|
||||
return xh_get_int(&dict->hash, key) != NULL;
|
||||
return xh_get_value(&dict->hash, key) != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_sym key)
|
||||
pic_dict_del(pic_state *pic, struct pic_dict *dict, pic_value key)
|
||||
{
|
||||
if (xh_get_int(&dict->hash, key) == NULL) {
|
||||
pic_errorf(pic, "no slot named ~s found in dictionary", pic_sym_value(key));
|
||||
if (xh_get_value(&dict->hash, key) == NULL) {
|
||||
pic_errorf(pic, "no slot named ~s found in dictionary", key);
|
||||
}
|
||||
|
||||
xh_del_int(&dict->hash, key);
|
||||
xh_del_value(&dict->hash, key);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
@ -88,8 +149,7 @@ pic_dict_dictionary(pic_state *pic)
|
|||
dict = pic_make_dict(pic);
|
||||
|
||||
for (i = 0; i < argc; i += 2) {
|
||||
pic_assert_type(pic, argv[i], sym);
|
||||
pic_dict_set(pic, dict, pic_sym(argv[i]), argv[i+1]);
|
||||
pic_dict_set(pic, dict, argv[i], argv[i+1]);
|
||||
}
|
||||
|
||||
return pic_obj_value(dict);
|
||||
|
@ -109,9 +169,9 @@ static pic_value
|
|||
pic_dict_dictionary_ref(pic_state *pic)
|
||||
{
|
||||
struct pic_dict *dict;
|
||||
pic_sym key;
|
||||
pic_value key;
|
||||
|
||||
pic_get_args(pic, "dm", &dict, &key);
|
||||
pic_get_args(pic, "do", &dict, &key);
|
||||
|
||||
if (pic_dict_has(pic, dict, key)) {
|
||||
return pic_values2(pic, pic_dict_ref(pic, dict, key), pic_true_value());
|
||||
|
@ -124,10 +184,9 @@ static pic_value
|
|||
pic_dict_dictionary_set(pic_state *pic)
|
||||
{
|
||||
struct pic_dict *dict;
|
||||
pic_sym key;
|
||||
pic_value val;
|
||||
pic_value key, val;
|
||||
|
||||
pic_get_args(pic, "dmo", &dict, &key, &val);
|
||||
pic_get_args(pic, "doo", &dict, &key, &val);
|
||||
|
||||
pic_dict_set(pic, dict, key, val);
|
||||
|
||||
|
@ -138,9 +197,9 @@ static pic_value
|
|||
pic_dict_dictionary_del(pic_state *pic)
|
||||
{
|
||||
struct pic_dict *dict;
|
||||
pic_sym key;
|
||||
pic_value key;
|
||||
|
||||
pic_get_args(pic, "dm", &dict, &key);
|
||||
pic_get_args(pic, "do", &dict, &key);
|
||||
|
||||
pic_dict_del(pic, dict, key);
|
||||
|
||||
|
@ -169,7 +228,7 @@ pic_dict_dictionary_map(pic_state *pic)
|
|||
|
||||
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));
|
||||
item = pic_cons(pic, xh_key(it.e, pic_value), xh_val(it.e, pic_value));
|
||||
pic_push(pic, pic_apply1(pic, proc, item), list);
|
||||
}
|
||||
|
||||
|
@ -190,7 +249,7 @@ pic_dict_dictionary_for_each(pic_state *pic)
|
|||
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));
|
||||
item = pic_cons(pic, xh_key(it.e, pic_value), xh_val(it.e, pic_value));
|
||||
pic_apply1(pic, proc, item);
|
||||
|
||||
pic_gc_arena_restore(pic, ai);
|
||||
|
@ -210,7 +269,7 @@ pic_dict_dictionary_to_alist(pic_state *pic)
|
|||
|
||||
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));
|
||||
item = pic_cons(pic, xh_key(it.e, pic_value), xh_val(it.e, pic_value));
|
||||
pic_push(pic, item, alist);
|
||||
}
|
||||
|
||||
|
@ -228,8 +287,7 @@ pic_dict_alist_to_dictionary(pic_state *pic)
|
|||
dict = pic_make_dict(pic);
|
||||
|
||||
pic_for_each (e, pic_reverse(pic, alist)) {
|
||||
pic_assert_type(pic, pic_car(pic, e), sym);
|
||||
pic_dict_set(pic, dict, pic_sym(pic_car(pic, e)), pic_cdr(pic, e));
|
||||
pic_dict_set(pic, dict, pic_car(pic, e), pic_cdr(pic, e));
|
||||
}
|
||||
|
||||
return pic_obj_value(dict);
|
||||
|
@ -247,7 +305,7 @@ pic_dict_dictionary_to_plist(pic_state *pic)
|
|||
xh_begin(&it, &dict->hash);
|
||||
while (xh_next(&it)) {
|
||||
pic_push(pic, xh_val(it.e, pic_value), plist);
|
||||
pic_push(pic, pic_sym_value(xh_key(it.e, pic_sym)), plist);
|
||||
pic_push(pic, xh_key(it.e, pic_value), plist);
|
||||
}
|
||||
|
||||
return pic_reverse(pic, plist);
|
||||
|
@ -264,8 +322,7 @@ pic_dict_plist_to_dictionary(pic_state *pic)
|
|||
dict = pic_make_dict(pic);
|
||||
|
||||
for (e = pic_reverse(pic, plist); ! pic_nil_p(e); e = pic_cddr(pic, e)) {
|
||||
pic_assert_type(pic, pic_car(pic, e), sym);
|
||||
pic_dict_set(pic, dict, pic_sym(pic_car(pic, e)), pic_cadr(pic, e));
|
||||
pic_dict_set(pic, dict, pic_car(pic, e), pic_cadr(pic, e));
|
||||
}
|
||||
|
||||
return pic_obj_value(dict);
|
||||
|
|
1
gc.c
1
gc.c
|
@ -498,6 +498,7 @@ gc_mark_object(pic_state *pic, struct pic_object *obj)
|
|||
|
||||
xh_begin(&it, &dict->hash);
|
||||
while (xh_next(&it)) {
|
||||
gc_mark(pic, xh_key(it.e, pic_value));
|
||||
gc_mark(pic, xh_val(it.e, pic_value));
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -19,11 +19,11 @@ struct pic_dict {
|
|||
|
||||
struct pic_dict *pic_make_dict(pic_state *);
|
||||
|
||||
pic_value pic_dict_ref(pic_state *, struct pic_dict *, pic_sym);
|
||||
void pic_dict_set(pic_state *, struct pic_dict *, pic_sym, pic_value);
|
||||
void pic_dict_del(pic_state *, struct pic_dict *, pic_sym);
|
||||
pic_value pic_dict_ref(pic_state *, struct pic_dict *, pic_value);
|
||||
void pic_dict_set(pic_state *, struct pic_dict *, pic_value, pic_value);
|
||||
void pic_dict_del(pic_state *, struct pic_dict *, pic_value);
|
||||
size_t pic_dict_size(pic_state *, struct pic_dict *);
|
||||
bool pic_dict_has(pic_state *, struct pic_dict *, pic_sym);
|
||||
bool pic_dict_has(pic_state *, struct pic_dict *, pic_value);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
4
proc.c
4
proc.c
|
@ -61,13 +61,13 @@ pic_attr(pic_state *pic, struct pic_proc *proc)
|
|||
pic_value
|
||||
pic_attr_ref(pic_state *pic, struct pic_proc *proc, const char *key)
|
||||
{
|
||||
return pic_dict_ref(pic, pic_attr(pic, proc), pic_intern_cstr(pic, key));
|
||||
return pic_dict_ref(pic, pic_attr(pic, proc), pic_sym_value(pic_intern_cstr(pic, key)));
|
||||
}
|
||||
|
||||
void
|
||||
pic_attr_set(pic_state *pic, struct pic_proc *proc, const char *key, pic_value v)
|
||||
{
|
||||
pic_dict_set(pic, pic_attr(pic, proc), pic_intern_cstr(pic, key), v);
|
||||
pic_dict_set(pic, pic_attr(pic, proc), pic_sym_value(pic_intern_cstr(pic, key)), v);
|
||||
}
|
||||
|
||||
static pic_value
|
||||
|
|
4
write.c
4
write.c
|
@ -336,7 +336,9 @@ write_core(struct writer_control *p, pic_value obj)
|
|||
xfprintf(file, "#.(dictionary");
|
||||
xh_begin(&it, &pic_dict_ptr(obj)->hash);
|
||||
while (xh_next(&it)) {
|
||||
xfprintf(file, " '%s ", pic_symbol_name(pic, xh_key(it.e, pic_sym)));
|
||||
xfprintf(file, " '");
|
||||
write_core(p, xh_key(it.e, pic_value));
|
||||
xfprintf(file, " ");
|
||||
write_core(p, xh_val(it.e, pic_value));
|
||||
}
|
||||
xfprintf(file, ")");
|
||||
|
|
Loading…
Reference in New Issue