From 2ec0f6e63f9c42750f09af4a7f03be832a2ca28a Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 11 Jun 2019 19:27:18 -0700 Subject: New function: hash-peek. * hash.c (hash_peek): New function. (hash_init): hash-peek intrinsic registered. * hash.h (hash_peek): Declared. * txr.1: Documented. --- hash.c | 26 ++++++++++++++++++++++++++ hash.h | 1 + txr.1 | 33 +++++++++++++++++++++++++-------- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/hash.c b/hash.c index fcabb5bd..0d8aaef9 100644 --- a/hash.c +++ b/hash.c @@ -973,6 +973,31 @@ val hash_next(val iter) return us_car(hi->cons); } +val hash_peek(val iter) +{ + val self = lit("hash-peek"); + struct hash_iter *hi = coerce(struct hash_iter *, + cobj_handle(self, iter, hash_iter_s)); + val hash = hi->hash; + struct hash *h = hash ? coerce(struct hash *, hash->co.handle) : 0; + cnum chain = hi->chain; + val cell = hi->cons; + + if (!h) + return nil; + if (cell) { + val peek = us_cdr(cell); + if (peek) + return us_car(peek); + } + do { + if (++chain >= h->modulus) + return nil; + cell = vecref(h->table, num_fast(chain)); + } while (!cell); + return us_car(cell); +} + val maphash(val fun, val hash) { val iter = hash_begin(hash); @@ -1651,6 +1676,7 @@ void hash_init(void) reg_fun(intern(lit("hash-revget"), user_package), func_n4o(hash_revget, 2)); reg_fun(intern(lit("hash-begin"), user_package), func_n1(hash_begin)); reg_fun(intern(lit("hash-next"), user_package), func_n1(hash_next)); + reg_fun(intern(lit("hash-peek"), user_package), func_n1(hash_peek)); reg_fun(intern(lit("set-hash-str-limit"), system_package), func_n1(set_hash_str_limit)); reg_fun(intern(lit("set-hash-rec-limit"), system_package), diff --git a/hash.h b/hash.h index baa27529..66cc55a8 100644 --- a/hash.h +++ b/hash.h @@ -49,6 +49,7 @@ val hashp(val obj); val maphash(val func, val hash); val hash_begin(val hash); val hash_next(val iter); +val hash_peek(val iter); val hash_eql(val obj); val hash_equal(val obj, val seed); val hashv(struct args *args); diff --git a/txr.1 b/txr.1 index 6d409c02..07c07dec 100644 --- a/txr.1 +++ b/txr.1 @@ -43264,10 +43264,11 @@ applies first, as above. If that is true, and the two hashes have the same number of elements, the result is falsified. -.coNP Functions @ hash-begin and @ hash-next +.coNP Functions @, hash-begin @ hash-next and @ hash-peek .synb .mets (hash-begin << hash ) .mets (hash-next << hash-iter ) +.mets (hash-peek << hash-iter ) .syne .desc The @@ -43279,19 +43280,35 @@ one by one. The .code hash-next -function applies to a hash iterator returned by +function's +.meta hash-iter +argument is a hash iterator returned by .codn hash-begin . - -If unvisited entries remain, it returns the next one as a cons cell -whose +If unvisited entries remain in +.metn hash , +then +.code hash-next +returns the next one as a cons cell whose .code car holds the key and whose .code cdr -holds the value. - -If no more entries remain to be visited, it returns +holds the value. That entry is then considered visited by the iterator. +If no more entries remain to be visited, +.code hash-next +returns .codn nil . +The +.code hash-peek +function returns the same value that a subsequent call to +.code hash-next +will return for the same +.metn hash-iter , +without changing the state of +.metn hash-iter . +That is to say, if a cell representing a hash entry is returned, that entry +remains unvisited by the iterator. + .coNP Macro @ with-hash-iter .synb .mets (with-hash-iter >> ( isym < hash-form >> [ ksym <> [ vsym ]]) -- cgit v1.2.3