summaryrefslogtreecommitdiffstats
path: root/combi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-12-26 20:02:16 -0800
committerKaz Kylheku <kaz@kylheku.com>2023-12-26 20:02:16 -0800
commitb4cdcb7e64573a849f21a61a1c0438ddb72fd54f (patch)
tree2bb95ef0ed809488674aa70f5758f3a7216a318c /combi.c
parent4e359b13774cccfdcfa0f4db8bc3c07d8c9d65e3 (diff)
downloadtxr-b4cdcb7e64573a849f21a61a1c0438ddb72fd54f.tar.gz
txr-b4cdcb7e64573a849f21a61a1c0438ddb72fd54f.tar.bz2
txr-b4cdcb7e64573a849f21a61a1c0438ddb72fd54f.zip
perm: support general sequences.
* combi.c (perm_seq_gen_fun, perm_seq): New functions. (perm): Call perm_seq in default case to handle more sequence kinds.
Diffstat (limited to 'combi.c')
-rw-r--r--combi.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/combi.c b/combi.c
index 7bf6f6a6..5d116aed 100644
--- a/combi.c
+++ b/combi.c
@@ -210,6 +210,29 @@ static val perm_str(val p, val k)
}
}
+static val perm_seq_gen_fun(val state)
+{
+ val p = vecref(state, zero);
+ val kk = vecref(state, one);
+ val out = vector(kk, nil);
+ perm_gen_fun_common(state, out, perm_vec_gen_fill);
+ return make_like(out, p);
+}
+
+static val perm_seq(val p, val k)
+{
+ if (k == zero) {
+ return cons(make_like(nil, p), nil);
+ } else {
+ val vec = vec_seq(p);
+ val state = perm_init_common(vec, k);
+ if (!state)
+ return nil;
+ return generate(func_f0(state, perm_while_fun),
+ func_f0(state, perm_seq_gen_fun));
+ }
+}
+
val perm(val seq, val k)
{
if (null_or_missing_p(k)) {
@@ -235,7 +258,7 @@ val perm(val seq, val k)
case LIT:
return perm_str(seq, k);
default:
- type_mismatch(lit("perm: ~s is not a sequence"), seq, nao);
+ return perm_seq(seq, k);
}
}