summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-06-17 06:37:32 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-06-17 06:37:32 -0700
commit5b140a070a99937da7c0b1fac9c23b7a281be82f (patch)
tree8e127a4b5fedaa372738a9a9cec0a735d7ef0554
parent4a223e77f8bf67c9236232bce354d60951b25bed (diff)
downloadtxr-5b140a070a99937da7c0b1fac9c23b7a281be82f.tar.gz
txr-5b140a070a99937da7c0b1fac9c23b7a281be82f.tar.bz2
txr-5b140a070a99937da7c0b1fac9c23b7a281be82f.zip
* eval.c (eval_init): register tuples as intrinsic.
* lib.c (tuples_func): New static function. (tuples): New function. * lib.h (tuples): Declared. * txr.1: Documented.
-rw-r--r--ChangeLog11
-rw-r--r--eval.c1
-rw-r--r--lib.c35
-rw-r--r--lib.h1
-rw-r--r--txr.133
5 files changed, 81 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index f4eb7b50..0385c09b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2014-06-17 Kaz Kylheku <kaz@kylheku.com>
+
+ * eval.c (eval_init): register tuples as intrinsic.
+
+ * lib.c (tuples_func): New static function.
+ (tuples): New function.
+
+ * lib.h (tuples): Declared.
+
+ * txr.1: Documented.
+
2014-06-16 Kaz Kylheku <kaz@kylheku.com>
* lib.c (obj_print): Render character DC00 as "pnul".
diff --git a/eval.c b/eval.c
index 2720b76a..d9acfda4 100644
--- a/eval.c
+++ b/eval.c
@@ -3254,6 +3254,7 @@ void eval_init(void)
reg_fun(intern(lit("last"), user_package), func_n1(last));
reg_fun(intern(lit("flatten"), user_package), func_n1(flatten));
reg_fun(intern(lit("flatten*"), user_package), func_n1(lazy_flatten));
+ reg_fun(intern(lit("tuples"), user_package), func_n3o(tuples, 2));
reg_fun(intern(lit("memq"), user_package), func_n2(memq));
reg_fun(intern(lit("memql"), user_package), func_n2(memql));
reg_fun(intern(lit("memqual"), user_package), func_n2(memqual));
diff --git a/lib.c b/lib.c
index 52c7fa5d..e505225a 100644
--- a/lib.c
+++ b/lib.c
@@ -1245,6 +1245,41 @@ val lazy_flatten(val list)
}
}
+static val tuples_func(val env, val lcons)
+{
+ list_collect_decl (out, ptail);
+ cons_bind (seq_in, envr, env);
+ cons_bind (n, fill, envr);
+ val seq = seq_in;
+ val count;
+
+ for (count = n; count != zero && seq; count = minus(count, one))
+ list_collect(ptail, pop(&seq));
+
+ if (!missingp(fill))
+ for (; gt(count, zero); count = minus(count, one))
+ list_collect(ptail, fill);
+
+ rplaca(env, seq);
+
+ if (seq)
+ rplacd(lcons, make_lazy_cons(lcons_fun(lcons)));
+ rplaca(lcons, make_like(out, seq_in));
+
+ return nil;
+}
+
+val tuples(val n, val seq, val fill)
+{
+ seq = nullify(seq);
+
+ if (!seq)
+ return nil;
+
+ return make_lazy_cons(func_f1(cons(seq, cons(n, fill)),
+ tuples_func));
+}
+
cnum c_num(val num);
val eql(val left, val right)
diff --git a/lib.h b/lib.h
index 548a0696..1f25f623 100644
--- a/lib.h
+++ b/lib.h
@@ -441,6 +441,7 @@ val lazy_appendv(val lists);
val ldiff(val list1, val list2);
val flatten(val list);
val lazy_flatten(val list);
+val tuples(val n, val seq, val fill);
val memq(val obj, val list);
val memql(val obj, val list);
val memqual(val obj, val list);
diff --git a/txr.1 b/txr.1
index b0accf49..503b7771 100644
--- a/txr.1
+++ b/txr.1
@@ -10257,6 +10257,39 @@ The sort function is stable for sequences which are lists. This means that the
original order of items which are considered identical is preserved.
For strings and vectors, the sort is not stable.
+.SS Function tuples
+
+.TP
+Syntax:
+
+ (tuples <length> <sequence> [<fill-value>])
+
+.TP
+Description:
+
+The tuples function produces a lazy list which represents a reorganization
+of the elements of <sequence> into tuples of <length>, where <length>
+must be a positive integer.
+
+The length of the sequence might not be evenly divisible by the tuple length.
+In this case, if a <fill-value> argument is specified, then the last tuple
+is padded with enough repetitions of <fill-value> to make it have <length>
+elements. If <fill-value> is not specified, then the last tuple is left
+shorter than <length>.
+
+The output of the function is a list, but the tuples themselves are sequences
+of the same kind as <sequence>. If <sequence> is any kind of list, they
+are lists, and not lazy lists.
+
+.TP
+Examples:
+
+ (tuples 3 #(1 2 3 4 5 6 7 8) 0) -> (#(1 2 3) #(4 5 6) #(7 8 0))
+ (tuples 3 "abc") -> ("abc")
+ (tuples 3 "abcd") -> ("abc" "d")
+ (tuples 3 "abcd" #\z) -> ("abc" "dzz")
+ (tuples 3 (list 1 2) #\z) -> ((1 2 #\z))
+
.SS Function make-like
.TP