Changeset 245


Ignore:
Timestamp:
Jan 9, 2004, 1:27:27 PM (21 years ago)
Author:
Gary Byers
Message:

[N]BUTLAST fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lib/lists.lisp

    r6 r245  
    155155  (dolist (a x y) (push a y)))
    156156
    157 ;;; The outer loop finds the first non-null list.  Starting with this list
    158 ;;; the inner loop tacks on the remaining lists in the arguments
    159 
    160 
    161 (defun butlast (list &optional n)
     157
     158(defun butlast (list &optional (n 1 n-p))
    162159  "Returns a new list the same as List without the N last elements."
    163160  (setq list (require-type list 'list))
    164   (if (and n (or (not (fixnump n)) (< n 0))) (report-bad-arg n '(fixnump 0 *)))
    165   (let* ((count (if n (- (alt-list-length list) n) most-positive-fixnum))
    166          it tail)
    167     (declare (fixnum count))
    168     (do ((l list (cdr l)))
    169         ((if n (<= count 0)(not (consp (cdr l)))) it)
    170         (declare (list l))
    171         (let ((newtail (list (car l))))
    172           (cond (tail (rplacd (the cons tail) newtail))
    173                 (t (setq it newtail)))
    174           (setq tail newtail)
    175           (setq count (1- count))))))
    176 
    177 (defun alt-list-length (list)
    178   (let ((n 0))
    179     (declare (fixnum n))
    180     (while
    181       (consp list)
    182       (setq list (cdr (the list list)))
    183       (setq n (1+ n)))
    184     n))     
    185 
    186 (defun nbutlast (list &optional n)
     161  (when (and n-p
     162             (if (typep n 'fixnum)
     163               (< (the fixnum n) 0)
     164               (not (typep n 'unsigned-byte))))
     165    (report-bad-arg n 'unsigned-byte))
     166  (let* ((length (length list)))
     167    (declare (fixnum length))           ;guaranteed
     168    (when (< n length)
     169      (let* ((count (- length (the fixnum n)))
     170             (head (cons nil nil))
     171             (tail head))
     172        (declare (fixnum count) (list head tail) (dynamic-extent head))
     173        ;; Return a list of the first COUNT elements of list
     174        (dotimes (i count (cdr head))
     175          (setq tail (rplacd tail (cons (pop list) nil))))))))
     176
     177
     178(defun nbutlast (list &optional (n 1 n-p))
    187179  "Modifies List to remove the last N elements."
    188180  (setq list (require-type list 'list))
    189   (if (and n (or (not (fixnump n)) (< n 0))) (report-bad-arg n '(fixnum 0 *)))
    190   (let* ((count (if n (- (alt-list-length list) n) most-positive-fixnum)))
    191 
    192     (declare (fixnum count))
    193     (do ((last list l)
    194          (l list (cdr l)))
    195         ((if n (<= count 0)(not (consp (cdr l))))
    196          (if (eq l list) nil (progn (rplacd (the cons last) nil) list)))
    197       (declare (list l))
    198       (setq count (1- count)))))
    199 
     181  (when (and n-p
     182             (if (typep n 'fixnum)
     183               (< (the fixnum n) 0)
     184               (not (typep n 'unsigned-byte))))
     185    (report-bad-arg n 'unsigned-byte))
     186  (let* ((length (length list)))
     187    (declare (fixnum length))           ;guaranteed
     188    (when (< n length)
     189      (let* ((count (1- (the fixnum (- length (the fixnum n)))))
     190             (tail list))
     191        (declare (fixnum count) (list tail))
     192        (dotimes (i count (rplacd tail nil))
     193          (setq tail (cdr tail)))
     194        list))))
    200195     
    201196
Note: See TracChangeset for help on using the changeset viewer.