diff options
-rw-r--r-- | hash.c | 26 | ||||
-rw-r--r-- | hash.h | 1 | ||||
-rw-r--r-- | txr.1 | 33 |
3 files changed, 52 insertions, 8 deletions
@@ -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), @@ -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); @@ -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 ]]) |