summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-11 01:21:17 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-11 01:21:17 -0800
commita32e4c21286764c013950015108d745fbdcd97ae (patch)
tree69f35b4dd96b0cf2d99fdcea6068ef13969ec411
parent1e90ef3c7658e2770940f6cb870bb671733cc188 (diff)
downloadtxr-a32e4c21286764c013950015108d745fbdcd97ae.tar.gz
txr-a32e4c21286764c013950015108d745fbdcd97ae.tar.bz2
txr-a32e4c21286764c013950015108d745fbdcd97ae.zip
* combi.c (comb_hash_while_fun, comb_hash_gen_fun, comb_hash): New
static functions. (comb): Support hash tables. * hash.c (print_key_val): When values are nil, print in a more condensed way by omitting the second element. This notation is accepted as input already by the parser. (hash_insert_pair): New function. * txr.1: Description of comb updated to indicate that it works over hashes.
-rw-r--r--ChangeLog14
-rw-r--r--combi.c35
-rw-r--r--hash.c5
-rw-r--r--txr.114
4 files changed, 61 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index a899e546..ae58f4a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2014-02-11 Kaz Kylheku <kaz@kylheku.com>
+ * combi.c (comb_hash_while_fun, comb_hash_gen_fun, comb_hash): New
+ static functions.
+ (comb): Support hash tables.
+
+ * hash.c (print_key_val): When values are nil, print in a more condensed
+ way by omitting the second element. This notation is accepted as
+ input already by the parser.
+ (hash_insert_pair): New function.
+
+ * txr.1: Description of comb updated to indicate that it works over
+ hashes.
+
+2014-02-11 Kaz Kylheku <kaz@kylheku.com>
+
* arith.c: Remove inclusion of unneeded headers: <limits.h>
and <dirent.h>.
diff --git a/combi.c b/combi.c
index 2af2a051..e32957a4 100644
--- a/combi.c
+++ b/combi.c
@@ -33,6 +33,7 @@
#include "signal.h"
#include "unwind.h"
#include "eval.h"
+#include "hash.h"
#include "combi.h"
static val perm_while_fun(val state)
@@ -426,6 +427,33 @@ static val comb_str(val str, val k)
func_f0(state, comb_str_gen_fun));
}
+static val comb_hash_while_fun(val state)
+{
+ return car(car(state));
+}
+
+static val comb_hash_gen_fun(val hstate)
+{
+ cons_bind (state, hash, hstate);
+ val iter, out = make_similar_hash(hash);
+
+ for (iter = state; iter; iter = cdr(iter)) {
+ val pair = car(car(iter));
+ sethash(out, car(pair), cdr(pair));
+ }
+
+ comb_gen_fun_common(state);
+ return out;
+}
+
+
+static val comb_hash(val hash, val k)
+{
+ val hstate = cons(nreverse(k_conses(hash_alist(hash), k)), hash);
+ return generate(func_f0(hstate, comb_hash_while_fun),
+ func_f0(hstate, comb_hash_gen_fun));
+}
+
val comb(val seq, val k)
{
if (!integerp(k))
@@ -457,6 +485,13 @@ val comb(val seq, val k)
return nil;
return comb_str(seq, k);
default:
+ if (hashp(seq)) {
+ if (k == zero)
+ return cons(make_similar_hash(seq), nil);
+ if (gt(k, hash_count(seq)))
+ return nil;
+ return comb_hash(seq, k);
+ }
type_mismatch(lit("comb: ~s is not a sequence"), seq, nao);
}
}
diff --git a/hash.c b/hash.c
index 8ce4e4bb..6aac63a0 100644
--- a/hash.c
+++ b/hash.c
@@ -230,7 +230,10 @@ cnum cobj_hash_op(val obj)
static val print_key_val(val out, val key, val value)
{
- format(out, lit(" (~s ~s)"), key, value, nao);
+ if (value)
+ format(out, lit(" (~s ~s)"), key, value, nao);
+ else
+ format(out, lit(" (~s)"), key, nao);
return nil;
}
diff --git a/txr.1 b/txr.1
index f7b65d7d..2d7f5274 100644
--- a/txr.1
+++ b/txr.1
@@ -7957,18 +7957,20 @@ length <len> non-repeating combinations formed by taking items taken from
element of <seq> more than once. If <seq> contains no duplicates, then
the combinations contain no duplicates.
-Argument <len> must be a nonnegative integer, and <seq> must be a sequence.
+Argument <len> must be a nonnegative integer, and <seq> must be a sequence
+or a hash table.
-The combinations in the returned list are sequences of the same kind as <seq>.
+The combinations in the returned list are objects of the same kind as <seq>.
If <len> is zero, then a list containing one combination is returned, and that
permutations is of zero length.
-If <len> exceeds the length of <seq>, then an empty list is returned,
-since it is impossible to make a single non-repeating combination that
-requires more items than are available.
+If <len> exceeds the number of elements in <seq>, then an empty list is
+returned, since it is impossible to make a single non-repeating combination
+that requires more items than are available.
-The combinations are lexicographically ordered.
+If <seq> is a sequence, the returned combinations are lexicographically ordered.
+This requirement is not applicable when <seq> is a hash table.
.SS Function rcomb