diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-12-27 15:51:53 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-12-27 15:51:53 -0800 |
commit | 36fdbc7a4791ffdedf0658eb69963cffe08aaee1 (patch) | |
tree | 8b0ee66a9941acd4647d87c2dedaa4b5e51ac940 /combi.c | |
parent | 2b4dff1bc2c3274201cdda958037b9065ca974bf (diff) | |
download | txr-36fdbc7a4791ffdedf0658eb69963cffe08aaee1.tar.gz txr-36fdbc7a4791ffdedf0658eb69963cffe08aaee1.tar.bz2 txr-36fdbc7a4791ffdedf0658eb69963cffe08aaee1.zip |
rperm: support general sequences.
* combi.c (rperm_init): Take one more parameter.
Allocate the state vector to three elements and
put the extra value there.
(rperm_list, rperm_vec, rperm_str): Pass nil
for the extra value to rperm_init; these do not
use it.
(rperm_seq_gen_fun, rperm_seq): New functions.
These use the extra value to store the original
seq in the state, so that the elements of the
output sequence can be converted to the same type
of sequence as the input.
(rperm): Replace error throw in default case with
call to rperm_seq.
Diffstat (limited to 'combi.c')
-rw-r--r-- | combi.c | 29 |
1 files changed, 23 insertions, 6 deletions
@@ -262,12 +262,14 @@ val perm(val seq, val k) } } -static val rperm_init(val list, val k) +static val rperm_init(val list, val k, val extra) { val vec = vector(k, list); - val env = vector(two, nil); + val env = vector(three, nil); set(vecref_l(env, zero), list); set(vecref_l(env, one), vec); + if (extra) + set(vecref_l(env, two), extra); return env; } @@ -302,7 +304,7 @@ static val rperm_gen_fun(val env) static val rperm_list(val list, val k) { - val env = rperm_init(list, k); + val env = rperm_init(list, k, nil); return generate(func_f0(env, rperm_while_fun), func_f0(env, rperm_gen_fun)); } @@ -316,7 +318,7 @@ static val rperm_vec_gen_fun(val env) static val rperm_vec(val ve, val k) { val list = list_vec(ve); - val env = rperm_init(list, k); + val env = rperm_init(list, k, nil); return generate(func_f0(env, rperm_while_fun), func_f0(env, rperm_vec_gen_fun)); } @@ -330,11 +332,26 @@ static val rperm_str_gen_fun(val env) static val rperm_str(val str, val k) { val list = list_str(str); - val env = rperm_init(list, k); + val env = rperm_init(list, k, nil); return generate(func_f0(env, rperm_while_fun), func_f0(env, rperm_str_gen_fun)); } +static val rperm_seq_gen_fun(val env) +{ + val list = rperm_gen_fun(env); + val seq = env->v.vec[2]; + return make_like(list, seq); +} + +static val rperm_seq(val seq, val k) +{ + val list = list_seq(seq); + val env = rperm_init(list, k, seq); + return generate(func_f0(env, rperm_while_fun), + func_f0(env, rperm_seq_gen_fun)); +} + val rperm(val seq, val k) { if (!integerp(k)) @@ -365,7 +382,7 @@ val rperm(val seq, val k) return cons(string(L""), nil); return rperm_str(seq, k); default: - type_mismatch(lit("rperm: ~s is not a sequence"), seq, nao); + return rperm_seq(seq, k); } } |