[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Interesting subseq problem with Garnet.

Dear CLISP users,

Today I tried Garnet again (after loading opal/defs as Doug reported it seemed
to work fine at least I didn't get the error *** - UNIX error 9 (EBADF)..   as 
I reported yesterday) but of course I got the error with subseq using 0 in 
place of the end specifier.

*** - SUBSEQ: :END should be an integer >=0, not NIL

After this error I grebbed the subseq function from the CMU Common Lisp sources
and compiled and loaded it. I tested it first of course and it seems to work
just fine.

> (subseq "Hello" 3) 

(I am just testing here!!)
> (subseq "Hello" 3 4)
> (subseq '(a b c d e f) 3 nil)
(D E F)
> (subseq '#(1 2 3 4 5 6) 3 nil)
#(4 5 6)
> (subseq "Hello" 3 0) 

*** - MAKE-STRING: the string length -3 should be nonnegative fixnum 
1. Break>

And now:

> (subseq "Hello" 3 nil)
Works just fine.

But then I wanted to start up Gilt and guess what happened?
The Gilt Work Window, Gilt Commands and Gilt Motif Gadgets came up and I was
happier than ever and then the shock came.

> (gilt:do-go)

*** - SUBSEQ: :END should be an integer >=0, not NIL
1. Break>

I realy don't know where this error comes from but hopefully somebody out there
knows about it.

But anyway the sources for subseq are here.


(in-package 'lisp) 

;;; SUBSEQ cannot default end to the length of sequence since it is not 
;;; an error to supply nil for its value.  We must test for end being nil 
;;; in the body of the function, and this is actually done in the support 
;;; routines for other reasons (see above). 
(defun subseq (sequence start &optional end)
  "Returns a copy of a subsequence of SEQUENCE starting with element number 
   START and continuing to the end of SEQUENCE or the optional END."
  (seq-dispatch sequence
                (list-subseq* sequence start end) 
                (vector-subseq* sequence start end)))

(defun vector-subseq* (sequence start &optional end
  (declare (vector sequence) (fixnum start))
  (when (null end) (setf end (length sequence)))
  (do ((old-index start (1+ old-index))
       (new-index 0 (1+ new-index))
       (copy (make-sequence-like sequence (- end start)))
      ((= old-index end) copy)
    (declare (fixnum old-index new-index))
    (setf (aref copy new-index) (aref sequence old-index))))

(defun list-subseq* (sequence start &optional end)
  (declare (list sequence) (fixnum start))
  (if (and end (>= start (the fixnum end)))
      (let* ((groveled (nthcdr start sequence))
             (result (list (car groveled))))
        (if groveled
            (do ((list (cdr groveled) (cdr list))
                 (splice result (cdr (rplacd splice (list (car list))))
                 (index (1+ start) (1+ index)))
                ((or (atom list) (and end (= index (the fixnum end))))
              (declare (fixnum index)))))))

(defun make-sequence-of-type (type length)
  "Returns a sequence of the given TYPE and LENGTH."
  (declare (fixnum length))
  (case (type-specifier-atom type)
    (list (make-list length))
    ((bit-vector simple-bit-vector) (make-array length :element-type '(mod 2)))
    ((string simple-string base-string simple-base-string)
     (make-string length))
    (simple-vector (make-array length))
    ((array simple-array vector)
     (if (listp type)
         (make-array length :element-type (cadr type))
         (make-array length)))
     (make-sequence-of-type (result-type-or-lose type) length))))

(defun result-type-or-lose (type &optional nil-ok)
   ((subtypep type 'nil)
    (if nil-ok
        (error "NIL output type invalid for this sequence function.")))
   ((dolist (seq-type '(list bit-vector string vector) nil)
     (when (subtypep type seq-type)
        (return seq-type))))
    (error "~S is a bad type specifier for sequence functions." type))))

;;; Seq-Dispatch does an efficient type-dispatch on the given Sequence.

(defmacro seq-dispatch (sequence list-form array-form)
  `(if (listp ,sequence)

(defmacro elt-slice (sequences n)
  "Returns a list of the Nth element of each of the sequences.  Used by MAP
   and friends."
  `(mapcar #'(lambda (seq) (elt seq ,n)) ,sequences))

(defmacro make-sequence-like (sequence length)
  "Returns a sequence of the same type as SEQUENCE and the given LENGTH.
  `(make-sequence-of-type (type-of ,sequence) ,length))

(defmacro type-specifier-atom (type)
  "Returns the broad class of which TYPE is a specific subclass."
  `(if (atom ,type) ,type (car ,type)))

If somebody knows what's wrong now please tell me.

I look forward to hearing from you.