aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Antipov2014-05-15 18:59:02 +0400
committerDmitry Antipov2014-05-15 18:59:02 +0400
commitddc30c996a3d14e0163df6946ba96c9bcf73bd2f (patch)
tree6c0a2fafa8a124e0c6e12174321dc012226bb7a9
parent92491099f710794ee2be60721fae50d68c5ca162 (diff)
downloademacs-ddc30c996a3d14e0163df6946ba96c9bcf73bd2f.tar.gz
emacs-ddc30c996a3d14e0163df6946ba96c9bcf73bd2f.zip
* src/fns.c (Fnreverse): Allow vectors and bool vectors.
* doc/lispref/lists.texi (Building Cons Cells and Lists): Remove description of `nreverse' and generalize it... * doc/lispref/sequences.texi (Sequences): ...for sequences here. * tests/automated/fns-tests.el (fns-tests-nreverse) (fns-tests-nreverse-bool-vector): New tests.
-rw-r--r--doc/lispref/ChangeLog2
-rw-r--r--doc/lispref/lists.texi52
-rw-r--r--doc/lispref/sequences.texi69
-rw-r--r--src/ChangeLog1
-rw-r--r--src/fns.c60
-rw-r--r--test/ChangeLog2
-rw-r--r--test/automated/fns-tests.el32
7 files changed, 150 insertions, 68 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index d5fe02d2398..7d85e4059c9 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,7 +1,7 @@
12014-05-15 Dmitry Antipov <dmantipov@yandex.ru> 12014-05-15 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 * lists.texi (Building Cons Cells and Lists): Remove 3 * lists.texi (Building Cons Cells and Lists): Remove
4 description of `reverse' and generalize it... 4 description of `reverse' and `'nreverse' to generalize them...
5 * sequences.texi (Sequences): ...for sequences here. 5 * sequences.texi (Sequences): ...for sequences here.
6 6
72014-05-14 Glenn Morris <rgm@gnu.org> 72014-05-14 Glenn Morris <rgm@gnu.org>
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index 882dd440491..f724d5bd902 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -1124,58 +1124,6 @@ each time you run it! Here is what happens:
1124@end smallexample 1124@end smallexample
1125@end defun 1125@end defun
1126 1126
1127@defun nreverse list
1128@cindex reversing a list
1129 This function reverses the order of the elements of @var{list}.
1130Unlike @code{reverse}, @code{nreverse} alters its argument by reversing
1131the @sc{cdr}s in the cons cells forming the list. The cons cell that
1132used to be the last one in @var{list} becomes the first cons cell of the
1133value.
1134
1135 For example:
1136
1137@example
1138@group
1139(setq x '(a b c))
1140 @result{} (a b c)
1141@end group
1142@group
1143x
1144 @result{} (a b c)
1145(nreverse x)
1146 @result{} (c b a)
1147@end group
1148@group
1149;; @r{The cons cell that was first is now last.}
1150x
1151 @result{} (a)
1152@end group
1153@end example
1154
1155 To avoid confusion, we usually store the result of @code{nreverse}
1156back in the same variable which held the original list:
1157
1158@example
1159(setq x (nreverse x))
1160@end example
1161
1162 Here is the @code{nreverse} of our favorite example, @code{(a b c)},
1163presented graphically:
1164
1165@smallexample
1166@group
1167@r{Original list head:} @r{Reversed list:}
1168 ------------- ------------- ------------
1169| car | cdr | | car | cdr | | car | cdr |
1170| a | nil |<-- | b | o |<-- | c | o |
1171| | | | | | | | | | | | |
1172 ------------- | --------- | - | -------- | -
1173 | | | |
1174 ------------- ------------
1175@end group
1176@end smallexample
1177@end defun
1178
1179@defun sort list predicate 1127@defun sort list predicate
1180@cindex stable sort 1128@cindex stable sort
1181@cindex sorting lists 1129@cindex sorting lists
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index c96f1222f3f..da53990b449 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -260,6 +260,75 @@ x
260@end example 260@end example
261@end defun 261@end defun
262 262
263@defun nreverse seq
264@cindex reversing a list
265@cindex reversing a vector
266 This function reverses the order of the elements of @var{seq}.
267If @var{seq} is a list, @code{nreverse} alters its by reversing the @sc{cdr}s
268in the cons cells. The cons cell that used to be the last one in @var{seq}
269becomes the first cons cell of the value. If @var{seq} is a vector or
270bool vector, its items are placed in the same vector in a reversed order.
271
272 For example:
273
274@example
275@group
276(setq x '(a b c))
277 @result{} (a b c)
278@end group
279@group
280x
281 @result{} (a b c)
282(nreverse x)
283 @result{} (c b a)
284@end group
285@group
286;; @r{The cons cell that was first is now last.}
287x
288 @result{} (a)
289@end group
290@end example
291
292 To avoid confusion, we usually store the result of @code{nreverse}
293back in the same variable which held the original list:
294
295@example
296(setq x (nreverse x))
297@end example
298
299 Here is the @code{nreverse} of our favorite example, @code{(a b c)},
300presented graphically:
301
302@smallexample
303@group
304@r{Original list head:} @r{Reversed list:}
305 ------------- ------------- ------------
306| car | cdr | | car | cdr | | car | cdr |
307| a | nil |<-- | b | o |<-- | c | o |
308| | | | | | | | | | | | |
309 ------------- | --------- | - | -------- | -
310 | | | |
311 ------------- ------------
312@end group
313@end smallexample
314
315 For the vector, it is even simpler because you don't need setq:
316
317@example
318(setq x [1 2 3 4])
319 @result{} [1 2 3 4]
320(nreverse x)
321 @result{} [4 3 2 1]
322x
323 @result{} [4 3 2 1]
324@end example
325
326Note that unlike @code{reverse}, this function doesn't work with strings.
327Although you can alter string data by using @code{aset}, it is strongly
328encouraged to treat strings as immutable.
329
330@end defun
331
263@node Arrays 332@node Arrays
264@section Arrays 333@section Arrays
265@cindex array 334@cindex array
diff --git a/src/ChangeLog b/src/ChangeLog
index ce51b26cf43..f82a6a298ae 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,6 +1,7 @@
12014-05-15 Dmitry Antipov <dmantipov@yandex.ru> 12014-05-15 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 * fns.c (Freverse): Allow vectors, bool vectors and strings. 3 * fns.c (Freverse): Allow vectors, bool vectors and strings.
4 (Fnreverse): Allow vectors and bool vectors.
4 5
52014-05-14 Dmitry Antipov <dmantipov@yandex.ru> 62014-05-14 Dmitry Antipov <dmantipov@yandex.ru>
6 7
diff --git a/src/fns.c b/src/fns.c
index 8f9734cd7cc..1694f1c798d 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -1697,25 +1697,55 @@ changing the value of a sequence `foo'. */)
1697} 1697}
1698 1698
1699DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0, 1699DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
1700 doc: /* Reverse LIST by modifying cdr pointers. 1700 doc: /* Reverse order of items in a list or vector SEQ.
1701Return the reversed list. Expects a properly nil-terminated list. */) 1701If SEQ is a list, it should be nil-terminated, and reversed
1702 (Lisp_Object list) 1702by modifying cdr pointers. Return the reversed SEQ.
1703
1704Note that unlike `reverse', this function doesn't work with strings.
1705It is strongly encouraged to treat them as immutable. */)
1706 (Lisp_Object seq)
1703{ 1707{
1704 register Lisp_Object prev, tail, next; 1708 if (NILP (seq))
1709 return seq;
1710 else if (CONSP (seq))
1711 {
1712 Lisp_Object prev, tail, next;
1705 1713
1706 if (NILP (list)) return list; 1714 for (prev = Qnil, tail = seq; !NILP (tail); tail = next)
1707 prev = Qnil; 1715 {
1708 tail = list; 1716 QUIT;
1709 while (!NILP (tail)) 1717 CHECK_LIST_CONS (tail, tail);
1718 next = XCDR (tail);
1719 Fsetcdr (tail, prev);
1720 prev = tail;
1721 }
1722 seq = prev;
1723 }
1724 else if (VECTORP (seq))
1710 { 1725 {
1711 QUIT; 1726 ptrdiff_t i, size = ASIZE (seq);
1712 CHECK_LIST_CONS (tail, tail); 1727
1713 next = XCDR (tail); 1728 for (i = 0; i < size / 2; i++)
1714 Fsetcdr (tail, prev); 1729 {
1715 prev = tail; 1730 Lisp_Object tem = AREF (seq, i);
1716 tail = next; 1731 ASET (seq, i, AREF (seq, size - i - 1));
1732 ASET (seq, size - i - 1, tem);
1733 }
1717 } 1734 }
1718 return prev; 1735 else if (BOOL_VECTOR_P (seq))
1736 {
1737 ptrdiff_t i, size = bool_vector_size (seq);
1738
1739 for (i = 0; i < size / 2; i++)
1740 {
1741 bool tem = bool_vector_bitref (seq, i);
1742 bool_vector_set (seq, i, bool_vector_bitref (seq, size - i - 1));
1743 bool_vector_set (seq, size - i - 1, tem);
1744 }
1745 }
1746 else
1747 wrong_type_argument (Qarrayp, seq);
1748 return seq;
1719} 1749}
1720 1750
1721DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0, 1751DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
diff --git a/test/ChangeLog b/test/ChangeLog
index cd5398e9b99..3fed9759ca7 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,6 +1,8 @@
12014-05-15 Dmitry Antipov <dmantipov@yandex.ru> 12014-05-15 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 * automated/fns-tests.el: New file. 3 * automated/fns-tests.el: New file.
4 * automated/fns-tests.el (fns-tests-nreverse)
5 (fns-tests-nreverse-bool-vector): New tests.
4 6
52014-05-08 Glenn Morris <rgm@gnu.org> 72014-05-08 Glenn Morris <rgm@gnu.org>
6 8
diff --git a/test/automated/fns-tests.el b/test/automated/fns-tests.el
index 2e71854261e..577298cddf4 100644
--- a/test/automated/fns-tests.el
+++ b/test/automated/fns-tests.el
@@ -28,12 +28,44 @@
28 (should-error (reverse)) 28 (should-error (reverse))
29 (should-error (reverse 1)) 29 (should-error (reverse 1))
30 (should-error (reverse (make-char-table 'foo))) 30 (should-error (reverse (make-char-table 'foo)))
31 (should (equal [] (reverse [])))
32 (should (equal [0] (reverse [0])))
31 (should (equal [1 2 3 4] (reverse (reverse [1 2 3 4])))) 33 (should (equal [1 2 3 4] (reverse (reverse [1 2 3 4]))))
34 (should (equal '(a b c d) (reverse (reverse '(a b c d)))))
32 (should (equal "xyzzy" (reverse (reverse "xyzzy")))) 35 (should (equal "xyzzy" (reverse (reverse "xyzzy"))))
33 (should (equal "こんにちは / コンニチハ" (reverse (reverse "こんにちは / コンニチハ"))))) 36 (should (equal "こんにちは / コンニチハ" (reverse (reverse "こんにちは / コンニチハ")))))
34 37
38(ert-deftest fns-tests-nreverse ()
39 (should-error (nreverse))
40 (should-error (nreverse 1))
41 (should-error (nreverse (make-char-table 'foo)))
42 (should-error (nreverse "xyzzy"))
43 (let ((A []))
44 (nreverse A)
45 (should (equal A [])))
46 (let ((A [0]))
47 (nreverse A)
48 (should (equal A [0])))
49 (let ((A [1 2 3 4]))
50 (nreverse A)
51 (should (equal A [4 3 2 1])))
52 (let ((A [1 2 3 4]))
53 (nreverse A)
54 (nreverse A)
55 (should (equal A [1 2 3 4])))
56 (let* ((A [1 2 3 4])
57 (B (nreverse (nreverse A))))
58 (should (equal A B))))
59
35(ert-deftest fns-tests-reverse-bool-vector () 60(ert-deftest fns-tests-reverse-bool-vector ()
36 (let ((A (make-bool-vector 10 nil))) 61 (let ((A (make-bool-vector 10 nil)))
37 (dotimes (i 5) (aset A i t)) 62 (dotimes (i 5) (aset A i t))
38 (should (equal [nil nil nil nil nil t t t t t] (vconcat (reverse A)))) 63 (should (equal [nil nil nil nil nil t t t t t] (vconcat (reverse A))))
39 (should (equal A (reverse (reverse A)))))) 64 (should (equal A (reverse (reverse A))))))
65
66(ert-deftest fns-tests-nreverse-bool-vector ()
67 (let ((A (make-bool-vector 10 nil)))
68 (dotimes (i 5) (aset A i t))
69 (nreverse A)
70 (should (equal [nil nil nil nil nil t t t t t] (vconcat A)))
71 (should (equal [t t t t t nil nil nil nil nil] (vconcat (nreverse A))))))