summaryrefslogtreecommitdiffstats
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/hash.c b/hash.c
index 86b7a2f5..010cfbf6 100644
--- a/hash.c
+++ b/hash.c
@@ -54,7 +54,7 @@ struct hash {
val userdata;
cnum (*hash_fun)(val);
val (*assoc_fun)(val list, val key);
- val *(*acons_new_l_fun)(val *list, val key, val *new_p);
+ val *(*acons_new_l_fun)(val key, val *new_p, val *list);
};
struct hash_iter {
@@ -105,6 +105,7 @@ static cnum equal_hash(val obj)
return c_num(obj) & NUM_MAX;
case SYM:
case PKG:
+ case ENV:
switch (sizeof (mem_t *)) {
case 4:
return (((cnum) obj) & NUM_MAX) >> 4;
@@ -268,10 +269,10 @@ val make_hash(val weak_keys, val weak_vals, val equal_based)
val *gethash_l(val hash, val key, val *new_p)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
val *pchain = vecref_l(h->table, num(h->hash_fun(key) % h->modulus));
val old = *pchain;
- val *place = h->acons_new_l_fun(pchain, key, new_p);
+ val *place = h->acons_new_l_fun(key, new_p, pchain);
if (old != *pchain && ++h->count > 2 * h->modulus)
hash_grow(h);
return place;
@@ -279,7 +280,7 @@ val *gethash_l(val hash, val key, val *new_p)
val gethash(val hash, val key)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
val chain = *vecref_l(h->table, num(h->hash_fun(key) % h->modulus));
val found = h->assoc_fun(chain, key);
return cdr(found);
@@ -287,12 +288,20 @@ val gethash(val hash, val key)
val gethash_f(val hash, val key, val *found)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
val chain = *vecref_l(h->table, num(h->hash_fun(key) % h->modulus));
*found = h->assoc_fun(chain, key);
return cdr(*found);
}
+val gethash_n(val hash, val key, val notfound_val)
+{
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
+ val chain = *vecref_l(h->table, num(h->hash_fun(key) % h->modulus));
+ val existing = h->assoc_fun(chain, key);
+ return if3(existing, cdr(existing), notfound_val);
+}
+
val sethash(val hash, val key, val value)
{
val new_p;
@@ -309,7 +318,7 @@ val pushhash(val hash, val key, val value)
val remhash(val hash, val key)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
val *pchain = vecref_l(h->table, num(h->hash_fun(key) % h->modulus));
*pchain = alist_remove1(*pchain, key);
h->count--;
@@ -319,19 +328,19 @@ val remhash(val hash, val key)
val hash_count(val hash)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
return num(h->count);
}
val get_hash_userdata(val hash)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
return h->userdata;
}
val set_hash_userdata(val hash, val data)
{
- struct hash *h = (struct hash *) hash->co.handle;
+ struct hash *h = (struct hash *) cobj_handle(hash, hash_s);
val olddata = h->userdata;
h->userdata = data;
return olddata;
@@ -371,7 +380,7 @@ val hash_begin(val hash)
val hash_next(val *iter)
{
- struct hash_iter *hi = (struct hash_iter *) (*iter)->co.handle;
+ struct hash_iter *hi = (struct hash_iter *) cobj_handle(*iter, hash_iter_s);
val hash = hi->hash;
struct hash *h = (struct hash *) hash->co.handle;
if (hi->cons)