jscl icon indicating copy to clipboard operation
jscl copied to clipboard

(make-array 0 :fill-pointer t)

Open vlad-km opened this issue 4 years ago • 5 comments

JSCL

CL-USER> (setq v (make-array 0 :fill-pointer t))
ERROR: Not a number!

SBCL

CL-USER> (setq aa (make-array 0 :fill-pointer t))
#()

On an the array of 5000 lines of code, a long you can search for the cause of the error with the text Not a number! .

vlad-km avatar May 13 '21 09:05 vlad-km

CL-USER> (make-array 10 :fill-pointer 0)
#()
CL-USER> (make-array 10 :fill-pointer t)
ERROR: Not a number!
CL-USER> (make-array 10 :fill-pointer nil)
#(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)
CL-USER> 

That suggests it is in the fill-pointer descriptor when it is not a number at least.

davazp avatar May 13 '21 10:05 davazp

The error is from printing, not from make-array.

CL-USER> (defvar *w* (make-array 3 :fill-pointer t))
*W*
CL-USER> *w*
ERROR: Not a number!

svantevonerichsen6906 avatar May 13 '21 10:05 svantevonerichsen6906

I think the special value t for fill-pointer has to be handled at initialization. Also, 0-dimensional arrays are allowed, so check that there is exactly one dimension.

(defun make-array (dimensions &key element-type initial-element adjustable fill-pointer)
  (let* ((dimensions (ensure-list dimensions))
         (size (!reduce #'* dimensions 1))
         (array (make-storage-vector size)))
    ;; Upgrade type
    (if (eq element-type 'character)
        (progn
          (oset 1 array "stringp")
          (setf element-type 'character
                initial-element (or initial-element #\space)))
        (setf element-type t))

    (when (and (not (= (length dimensions) 1))
               fill-pointer)
      (error "FILL-POINTER can only be specified on one-dimensional arrays."))

    ;; Initialize array
    (storage-vector-fill array initial-element)
    ;; Record and return the object
    (setf (oget array "type") element-type)
    (setf (oget array "dimensions") dimensions)
    (setf (oget array "fillpointer")
          (if (eq fill-pointer t)
              (first dimensions)
              fill-pointer))
    array))

svantevonerichsen6906 avatar May 13 '21 10:05 svantevonerichsen6906

CLHS

If fill-pointer is non-nil, the array must be one-dimensional; that is, the array must be a vector. If fill-pointer is t, the length of the vector is used to initialize the fill pointer. If fill-pointer is an integer, it becomes the initial fill pointer for the vector.

So, yeah. It needs to be corrected in (make-array). Trivial error.

vlad-km avatar May 13 '21 11:05 vlad-km

SBCL

(vector-push-extend (setq fable (list 'fable))
              (setq fa (make-array 8
                                   :fill-pointer 2
                                   :initial-element 'sisyphus))) =>  2 
 (fill-pointer fa) =>  3

JSCL

(vector-push-extend (setq fable (list 'fable))
              (setq fa (make-array 8
                                   :fill-pointer 2
                                   :initial-element 'sisyphus))) =>  3 
 (fill-pointer fa) =>  3

vlad-km avatar May 19 '21 08:05 vlad-km

Closed #451

vlad-km avatar Sep 11 '22 02:09 vlad-km