diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2011-11-26 09:54:49 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2011-11-26 09:54:49 -0800 |
commit | bb83f68455149edd0acd6996115de881ed0e77a2 (patch) | |
tree | ebb45a058cc59b2c3b8a3c9e63fc2c0864c1ae6e /hash.c | |
parent | 21d250ce79f3c3a109731eeee7d67d757031dc1d (diff) | |
download | txr-bb83f68455149edd0acd6996115de881ed0e77a2.tar.gz txr-bb83f68455149edd0acd6996115de881ed0e77a2.tar.bz2 txr-bb83f68455149edd0acd6996115de881ed0e77a2.zip |
Task #11436
Lisp interpreter added.
* gc.c (finalize, mark_obj): Handle ENV objects.
* hash.c (struct hash): acons_new_l_fun function
pointer order of arguments change.
(equal_hash): Handle ENV.
(make_hash, gethash_l): Use cobj_handle for
type safety. Follow change in acons_new_l.
(gethash, gethash_f, remhash, hash_count,
hash_get_userdata, hash_set_userdata, hash_next): Use cobj_handle.
(gethash_n): New function.
* hash.h (gethash_n): Declared.
* lib.c (env_s): New symbol variable.
(code2type, equal): Handle ENV. (plusv, minusv, mul, mulv, trunc, mod,
gtv, ltv, gev, lev, maxv, minv, int_str): New functions.
(rehome_sym): New static function.
(func_f0, func_f1, func_f2, func_f3, func_f4, func_n0, func_n1,
func_n2, func_n3, func_n4): Initialize new fields of struct func.
(func_f0v, func_f1v, func_f2v, func_f3v, func_f4v,
func_n0v, func_n1v, func_n2v, func_n3v, func_n4v,
func_interp): New functions.
(apply): Function removed: sanely re-implemented in new eval.c file.
(funcall, funcall1, funcall2, funcall3, funcall4): Handle
variadic and interpreted functions.
(acons, acons_new, acons_new_l, aconsq_new, aconsq_new_l): Reordered
arguments for compatibility with Common Lisp acons.
(obj_init): Special hack to prepare hash_s symbol, which is
needed for type checking inside the hash table funtions invoked
by make_package, at a time when the symbol is not yet interned.
Initialize new env_s variable.
(obj_print, obj_pprint): Handle ENV. Fix confusing rendering of
of function type.
(init): Call new function eval_init.
* lib.h (enum type): New enumeration member ENV.
(struct func): functype member changed to bitfield.
New bitfied members minparam and variadic.
New members in f union: f0v, f1v, f2v, f3v,
f4v, n0v, n1v, n2v, n3v, n4v.
(struct env): New type.
(union obj): New member e of type struct env.
(env_s): Variable declared.
(plusv, minusv, mul, mulv, trunc, mod, gtv, ltv, gev, lev, maxv, minv,
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 29 |
1 files changed, 19 insertions, 10 deletions
@@ -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) |