From c269148bf9a039edff92b1dd7a415d30c21d3087 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 15 May 2014 10:01:46 +0400 Subject: [PATCH] * src/fns.c (Freverse): Allow vectors, bool vectors and strings. * doc/lispref/lists.texi (Building Cons Cells and Lists): Remove description of `reverse' and generalize it... * doc/lispref/sequences.texi (Sequences): ...for sequences here. --- doc/lispref/ChangeLog | 6 ++++ doc/lispref/lists.texi | 19 ----------- doc/lispref/sequences.texi | 43 +++++++++++++++++++++++++ src/ChangeLog | 4 +++ src/fns.c | 64 ++++++++++++++++++++++++++++++++++---- 5 files changed, 111 insertions(+), 25 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index b62a4daa051..d5fe02d2398 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,9 @@ +2014-05-15 Dmitry Antipov + + * lists.texi (Building Cons Cells and Lists): Remove + description of `reverse' and generalize it... + * sequences.texi (Sequences): ...for sequences here. + 2014-05-14 Glenn Morris * files.texi (Changing Files): Mention with-file-modes. diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index cde7d9ce44c..882dd440491 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi @@ -601,25 +601,6 @@ not a list, the sequence's elements do not become elements of the resulting list. Instead, the sequence becomes the final @sc{cdr}, like any other non-list final argument. -@defun reverse list -This function creates a new list whose elements are the elements of -@var{list}, but in reverse order. The original argument @var{list} is -@emph{not} altered. - -@example -@group -(setq x '(1 2 3 4)) - @result{} (1 2 3 4) -@end group -@group -(reverse x) - @result{} (4 3 2 1) -x - @result{} (1 2 3 4) -@end group -@end example -@end defun - @defun copy-tree tree &optional vecp This function returns a copy of the tree @code{tree}. If @var{tree} is a cons cell, this makes a new cons cell with the same @sc{car} and diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 01de4ccb0cd..c96f1222f3f 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -217,6 +217,49 @@ y @result{} [foo (69 2)] @end example @end defun +@defun reverse seq +@cindex string reverse +@cindex list reverse +@cindex vector reverse +@cindex sequence reverse +This function creates a new sequence whose elements are the elements +of @var{seq}, but in reverse order. The original argument @var{seq} +is @emph{not} altered. Note that char-table cannot be reversed. + +@example +@group +(setq x '(1 2 3 4)) + @result{} (1 2 3 4) +@end group +@group +(reverse x) + @result{} (4 3 2 1) +x + @result{} (1 2 3 4) +@end group +@group +(setq x [1 2 3 4]) + @result{} [1 2 3 4] +@end group +@group +(reverse x) + @result{} [4 3 2 1] +x + @result{} [1 2 3 4] +@end group +@group +(setq x "xyzzy") + @result{} "xyzzy" +@end group +@group +(reverse x) + @result{} "yzzyx" +x + @result{} "xyzzy" +@end group +@end example +@end defun + @node Arrays @section Arrays @cindex array diff --git a/src/ChangeLog b/src/ChangeLog index e78a32c26ca..ce51b26cf43 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2014-05-15 Dmitry Antipov + + * fns.c (Freverse): Allow vectors, bool vectors and strings. + 2014-05-14 Dmitry Antipov Minor cleanup for terminal setup. diff --git a/src/fns.c b/src/fns.c index 53819ed23aa..8f9734cd7cc 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1719,18 +1719,70 @@ Return the reversed list. Expects a properly nil-terminated list. */) } DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0, - doc: /* Reverse LIST, copying. Return the reversed list. + doc: /* Return the reversed copy of list, vector, or string SEQ. See also the function `nreverse', which is used more often. */) - (Lisp_Object list) + (Lisp_Object seq) { Lisp_Object new; - for (new = Qnil; CONSP (list); list = XCDR (list)) + if (NILP (seq)) + return Qnil; + else if (CONSP (seq)) { - QUIT; - new = Fcons (XCAR (list), new); + for (new = Qnil; CONSP (seq); seq = XCDR (seq)) + { + QUIT; + new = Fcons (XCAR (seq), new); + } + CHECK_LIST_END (seq, seq); + } + else if (VECTORP (seq)) + { + ptrdiff_t i, size = ASIZE (seq); + + new = make_uninit_vector (size); + for (i = 0; i < size; i++) + ASET (new, i, AREF (seq, size - i - 1)); } - CHECK_LIST_END (list, list); + else if (BOOL_VECTOR_P (seq)) + { + ptrdiff_t i; + EMACS_INT nbits = bool_vector_size (seq); + + new = make_uninit_bool_vector (nbits); + for (i = 0; i < nbits; i++) + bool_vector_set (new, i, bool_vector_bitref (seq, nbits - i - 1)); + } + else if (STRINGP (seq)) + { + ptrdiff_t size = SCHARS (seq), bytes = SBYTES (seq); + + if (size == bytes) + { + ptrdiff_t i; + + new = make_uninit_string (size); + for (i = 0; i < size; i++) + SSET (new, i, SREF (seq, size - i - 1)); + } + else + { + unsigned char *p, *q; + + new = make_uninit_multibyte_string (size, bytes); + p = SDATA (seq), q = SDATA (new) + bytes; + while (q > SDATA (new)) + { + int ch, len; + + ch = STRING_CHAR_AND_LENGTH (p, len); + p += len, q -= len; + CHAR_STRING (ch, q); + } + } + } + else + wrong_type_argument (Qsequencep, seq); return new; } -- 2.39.5