From 506575ce91cbed2c11c5484d140b12004fe6a92b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 1 May 2023 11:40:09 -0700 Subject: hash: new function, hash-props. We don't have a function in the hash table module which can create a populated hash table in one step without requiring the caller to create auxiliary lists. This new function fills that gap, albeit with some limitations. * hash.c (hash_props): New function. (hash_init): Register hash-props intrinsic. * tests/010/hash.tl: New tests. * txr.1: Documented. * stdlib/doc-syms.tl: Updated. --- hash.c | 21 +++++++++++++++++++++ hash.h | 1 + stdlib/doc-syms.tl | 1 + tests/010/hash.tl | 7 +++++++ txr.1 | 21 +++++++++++++++++++++ 5 files changed, 51 insertions(+) diff --git a/hash.c b/hash.c index 1b85e01f..f258bcb7 100644 --- a/hash.c +++ b/hash.c @@ -1613,6 +1613,26 @@ val hash_from_alist_v(val alist, struct args *hashv_args) return hash; } +val hash_props(struct args *plist) +{ + val self = lit("hash-props"); + args_decl_constsize(args, ARGS_MIN); + val hash = hashv(args); + cnum index = 0; + + while (args_two_more(plist, index)) { + val key = args_get(plist, &index); + val value = args_get(plist, &index); + sethash(hash, key, value); + } + + if (args_more(plist, index)) + uw_throwf(error_s, lit("~a: unpaired ~s argument"), + self, args_get(plist, &index), nao); + + return hash; +} + val hash_list(val keys, struct args *hashv_args) { val hash = hashv(hashv_args); @@ -2121,6 +2141,7 @@ void hash_init(void) reg_fun(hash_construct_s, func_n2(hash_construct)); reg_fun(intern(lit("hash-from-pairs"), user_package), func_n1v(hash_from_pairs_v)); reg_fun(intern(lit("hash-from-alist"), user_package), func_n1v(hash_from_alist_v)); + reg_fun(intern(lit("hash-props"), user_package), func_n0v(hash_props)); reg_fun(intern(lit("hash-list"), user_package), func_n1v(hash_list)); reg_fun(intern(lit("hash-zip"), user_package), func_n2v(hash_zip)); reg_fun(intern(lit("gethash"), user_package), func_n3o(gethash_n, 2)); diff --git a/hash.h b/hash.h index 22c1bd0e..cc1a0f1d 100644 --- a/hash.h +++ b/hash.h @@ -82,6 +82,7 @@ val hashl(val args); val hash_construct(val hashl_args, val pairs); val hash_from_pairs_v(val pairs, struct args *hashv_args); val hash_from_alist_v(val alist, struct args *hashv_args); +val hash_props(struct args *plist); val hash_list(val keys, struct args *hashv_args); val hash_zip(val keys, val vals, struct args *hashv_args); val group_by(val func, val seq, struct args *hashv_args); diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl index 2c9c14b1..029cecbd 100644 --- a/stdlib/doc-syms.tl +++ b/stdlib/doc-syms.tl @@ -953,6 +953,7 @@ ("hash-pairs" "N-00C9B125") ("hash-peek" "N-0225209D") ("hash-proper-subset" "N-024ACBBB") + ("hash-props" "N-026628B3") ("hash-reset" "N-0225209D") ("hash-revget" "N-02FBE776") ("hash-subset" "N-024ACBBB") diff --git a/tests/010/hash.tl b/tests/010/hash.tl index 7f662b51..558688af 100644 --- a/tests/010/hash.tl +++ b/tests/010/hash.tl @@ -20,3 +20,10 @@ (#\s 3) (#\u 1) (#\v 1) (#\y 1)) [group-reduce (hash) evenp + (range 1 10) 0] #H(() (t 30) (nil 25))) + +(mtest + (hash-props) #H(()) + (hash-props 1 2) #H(() (1 2)) + (hash-props 1 2 'a 'b) #H(() (1 2) (a b)) + (hash-props 1) :error + (hash-props 1 2 'a) :error) diff --git a/txr.1 b/txr.1 index 232c174a..6927bd13 100644 --- a/txr.1 +++ b/txr.1 @@ -55442,6 +55442,27 @@ is longer than .metn value-seq , then the excess keys are ignored, and vice versa. +.coNP Function @ hash-props +.synb +.mets (hash-props >> { key << value }*) +.syne +.desc +The +.code hash-props +function constructs a populated hash table without requiring +the caller to construct a list of entries. The hash table +contents are specified as direct arguments. + +The +.code hash-props +function requires an even number of arguments, which +are interleaved key-value pairs. + +The returned hash table is +.codn equal -based, +and no parameters are available for customizing any of +its properties, such as weakness. + .coNP Function @ hash-update .synb .mets (hash-update < hash << function ) -- cgit v1.2.3