diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-07-22 07:18:58 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-07-22 07:18:58 -0700 |
commit | cddd91863740e560ae95ccdd2be5aa0e128713ed (patch) | |
tree | 5a3e8391212f63afd0366a7543e25ea5d9eaf78f /hash.c | |
parent | 8eba1ea78d3c264673b957f20013694fd77ddf07 (diff) | |
download | txr-cddd91863740e560ae95ccdd2be5aa0e128713ed.tar.gz txr-cddd91863740e560ae95ccdd2be5aa0e128713ed.tar.bz2 txr-cddd91863740e560ae95ccdd2be5aa0e128713ed.zip |
hash: change make_hash interface.
The make_hash function now takes the hash_weak_opt_t
enumeration instead of a pair of flags.
* hash.c (do_make_hash): Take enum argument instead of pair of
flags. Just store the option; nothing to calculate.
(weak_opt_from_flags): New static function.
(tweak_hash): Function removed.
(make_seeded_hash): Adjust to new do_make_hash interface with
help from weak_opt_from_flags.
(make_hash, make_eq_hash): Take enum argument instead of pair
of flags.
(hashv): Calculate hash_weak_opt_t enum from the extracted
flags, pass down to make_eq_hash or make_hash.
* hash.h (tweak_hash): Declration removed.
(make_hash, make_eq_hash): Declarations updated.
* eval.c (me_case, expand_switch): Update make_hash
calls to new style.
(eval_init): Update make_hash calls and get rid of tweak_hash
calls. This renders the tweak_hash function unused.
* ffi.c (make_ffi_type_enum, ffi_init): Update make_hash calls
to new style.
* filter.c (make_trie, trie_add, filter_init): Likewise.
* lib.c (make_package_common, obj_init, obj_print): Likewise.
* lisplib.c (lisplib_init): Likewise.
* match.c (dir_tables_init): Likewise.
* parser.c (parser_circ_def, repl, parse_init): Likewise.
* parser.l (parser_l_init): Likewise.
* struct.c (struct_init, get_slot_syms): Likewise.
* sysif.c (get_env_hash): Likewise.
* lex.yy.c.shipped, y.tab.c.shipped: Updated.
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 61 |
1 files changed, 36 insertions, 25 deletions
@@ -790,17 +790,17 @@ static_def(struct hash_ops hash_equal_ops = hash_ops_init(equal_hash, equal, hash_assoc, hash_acons_new_c)); -static val do_make_hash(val weak_keys, val weak_vals, - hash_type_t type, val seed) +static val do_make_hash(hash_weak_opt_t wkopt, hash_type_t type, val seed) { val self = lit("make-hash"); - if (weak_keys && type == hash_type_equal) { + if (type == hash_type_equal && + wkopt != hash_weak_none && wkopt != hash_weak_vals) + { uw_throwf(error_s, lit("make-hash: bad combination :weak-keys with :equal-based"), nao); } else { - int wkopt = ((weak_vals != nil) << 1) | (weak_keys != nil); struct hash *h = coerce(struct hash *, chk_malloc(sizeof *h)); val mod = num_fast(256); val table = vector(mod, nil); @@ -809,7 +809,7 @@ static val do_make_hash(val weak_keys, val weak_vals, h->seed = convert(u32_t, c_unum(default_arg(seed, if3(hash_seed_s, hash_seed, zero)), self)); - h->wkopt = convert(hash_weak_opt_t, wkopt); + h->wkopt = wkopt; h->modulus = c_num(mod, self); h->count = 0; h->table = table; @@ -817,13 +817,6 @@ static val do_make_hash(val weak_keys, val weak_vals, h->usecount = 0; - if (weak_keys) { - if (weak_keys == weak_and_k) - h->wkopt = hash_weak_and; - else if (weak_keys == weak_or_k) - h->wkopt = hash_weak_or; - } - switch (type) { case hash_type_eq: h->hops = &hash_eq_ops; @@ -841,28 +834,43 @@ static val do_make_hash(val weak_keys, val weak_vals, } } -void tweak_hash(val hash, hash_weak_opt_t wkopt) +static hash_weak_opt_t weak_opt_from_flags(val weak_keys, val weak_vals) { - val self = lit("internal-error"); - struct hash *h = coerce(struct hash *, cobj_handle(self, hash, hash_cls)); - h->wkopt = wkopt; + if (weak_keys) { + if (weak_keys == weak_and_k) + return hash_weak_and; + if (weak_keys == weak_or_k) + return hash_weak_or; + } + + switch (!!weak_vals << 1 | !!weak_keys) { + case 0: return hash_weak_none; + case 1: return hash_weak_keys; + case 2: return hash_weak_vals; + case 3: return hash_weak_or; + default: + /* notreached */ + abort(); + } } val make_seeded_hash(val weak_keys, val weak_vals, val equal_based, val seed) { - return do_make_hash(weak_keys, weak_vals, + return do_make_hash(weak_opt_from_flags(weak_keys, weak_vals), if3(equal_based, hash_type_equal, hash_type_eql), seed); } -val make_hash(val weak_keys, val weak_vals, val equal_based) +val make_hash(hash_weak_opt_t wkopt, val equal_based) { - return make_seeded_hash(weak_keys, weak_vals, equal_based, nil); + return do_make_hash(wkopt, + if3(equal_based, hash_type_equal, hash_type_eql), + nil); } -val make_eq_hash(val weak_keys, val weak_vals) +val make_eq_hash(hash_weak_opt_t wkopt) { - return do_make_hash(weak_keys, weak_vals, hash_type_eq, nil); + return do_make_hash(wkopt, hash_type_eq, nil); } val make_similar_hash(val existing) @@ -1429,6 +1437,7 @@ val hashv(struct args *args) { weak_or_k, nil, &wor }, { userdata_k, t, &userdata } }; + hash_weak_opt_t wkopt = hash_weak_none; args_keys_extract(args, akv, sizeof akv / sizeof akv[0]); @@ -1437,15 +1446,17 @@ val hashv(struct args *args) self, weak_and_k, weak_or_k, nao); if (wand) - wkeys = weak_and_k; + wkopt = hash_weak_and; else if (wor) - wkeys = weak_or_k; + wkopt = hash_weak_or; + else + wkopt = weak_opt_from_flags(wkeys, wvals); { val ebp = equal_based_p(equal, eql, eq, wkeys); val hash = if3(eq, - make_eq_hash(wkeys, wvals), - make_hash(wkeys, wvals, ebp)); + make_eq_hash(wkopt), + make_hash(wkopt, ebp)); if (userdata) set_hash_userdata(hash, userdata); return hash; |