(in-package "SB!IMPL")
-(file-comment
- "$Header$")
-
#!-sb-fluid
(declaim (inline fill-pointer array-has-fill-pointer-p adjustable-array-p
array-displacement))
\f
;;;; miscellaneous accessor functions
-;;; These functions are needed by the interpreter, 'cause the compiler inlines
-;;; them.
+;;; These functions are needed by the interpreter, 'cause the compiler
+;;; inlines them.
(macrolet ((def-frob (name)
`(progn
(defun ,name (array)
(fixnum index))
(%check-bound array bound index))
-;;; The guts of the WITH-ARRAY-DATA macro. Note that this function is
-;;; only called if we have an array header or an error, so it doesn't
-;;; have to be too tense.
+;;; the guts of the WITH-ARRAY-DATA macro (except when DEFTRANSFORM
+;;; %WITH-ARRAY-DATA takes over)
(defun %with-array-data (array start end)
(declare (array array) (type index start) (type (or index null) end))
;; FIXME: The VALUES declaration here is correct, but as of SBCL
;;; These functions are used in the implementation of MAKE-ARRAY for
;;; complex arrays. There are lots of transforms to simplify
-;;; MAKE-ARRAY is transformed away for various easy cases, but not for
-;;; all reasonable cases, so e.g. as of sbcl-0.6.6 we still make full
-;;; calls to MAKE-ARRAY for any non-simple array. Thus, there's some
-;;; value to making this somewhat efficient, at least not doing full
-;;; calls to SUBTYPEP in the easy cases.
+;;; MAKE-ARRAY for various easy cases, but not for all reasonable
+;;; cases, so e.g. as of sbcl-0.6.6 we still make full calls to
+;;; MAKE-ARRAY for any non-simple array. Thus, there's some value to
+;;; making this somewhat efficient, at least not doing full calls to
+;;; SUBTYPEP in the easy cases.
(defun %vector-type-code (type)
(case type
;; Pick off some easy common cases.
(initial-element nil initial-element-p)
initial-contents adjustable fill-pointer
displaced-to displaced-index-offset)
- #!+sb-doc
- "Creates an array of the specified Dimensions. See manual for details."
(let* ((dimensions (if (listp dimensions) dimensions (list dimensions)))
(array-rank (length (the list dimensions)))
(simple (and (null fill-pointer)
(null displaced-to))))
(declare (fixnum array-rank))
(when (and displaced-index-offset (null displaced-to))
- (error "Can't specify :displaced-index-offset without :displaced-to"))
+ (error "can't specify :DISPLACED-INDEX-OFFSET without :DISPLACED-TO"))
(if (and simple (= array-rank 1))
;; Its a (simple-array * (*))
(multiple-value-bind (type bits) (%vector-type-code element-type)
(fill array initial-element))
(when initial-contents
(when initial-element
- (error "Cannot specify both :initial-element and ~
- :initial-contents"))
+ (error "can't specify both :INITIAL-ELEMENT and ~
+ :INITIAL-CONTENTS"))
(unless (= length (length initial-contents))
- (error "~D elements in the initial-contents, but the ~
- vector length is ~D."
+ (error "There are ~D elements in the :INITIAL-CONTENTS, but ~
+ the vector length is ~D."
(length initial-contents)
length))
(replace array initial-contents))
(unless (and (fixnump fill-pointer)
(>= fill-pointer 0)
(<= fill-pointer length))
- (error "Invalid fill-pointer ~D"
+ (error "invalid fill-pointer ~D"
fill-pointer))
fill-pointer))))
(setf (%array-fill-pointer-p array) t))
(setf (%array-data-vector array) data)
(cond (displaced-to
(when (or initial-element-p initial-contents)
- (error "Neither :initial-element nor :initial-contents ~
- can be specified along with :displaced-to"))
+ (error "Neither :INITIAL-ELEMENT nor :INITIAL-CONTENTS ~
+ can be specified along with :DISPLACED-TO"))
(let ((offset (or displaced-index-offset 0)))
(when (> (+ offset total-size)
(array-total-size displaced-to))
(incf axis)))
array))))
-;;; DATA-VECTOR-FROM-INITS returns a simple vector that has the specified array
-;;; characteristics. Dimensions is only used to pass to FILL-DATA-VECTOR
-;;; for error checking on the structure of initial-contents.
+;;; DATA-VECTOR-FROM-INITS returns a simple vector that has the
+;;; specified array characteristics. Dimensions is only used to pass
+;;; to FILL-DATA-VECTOR for error checking on the structure of
+;;; initial-contents.
(defun data-vector-from-inits (dimensions total-size element-type
initial-contents initial-element
initial-element-p)
(when (and initial-contents initial-element-p)
- (error "Cannot supply both :initial-contents and :initial-element to
- either make-array or adjust-array."))
+ (error "cannot supply both :INITIAL-CONTENTS and :INITIAL-ELEMENT to
+ either MAKE-ARRAY or ADJUST-ARRAY."))
(let ((data (if initial-element-p
(make-array total-size
:element-type element-type
(incf index))
(t
(unless (typep contents 'sequence)
- (error "Malformed :INITIAL-CONTENTS. ~S is not a ~
+ (error "malformed :INITIAL-CONTENTS: ~S is not a ~
sequence, but ~D more layer~:P needed."
contents
(- (length dimensions) axis)))
(unless (= (length contents) (car dims))
- (error "Malformed :INITIAL-CONTENTS. Dimension of ~
+ (error "malformed :INITIAL-CONTENTS: Dimension of ~
axis ~D is ~D, but ~S is ~D long."
axis (car dims) contents (length contents)))
(if (listp contents)
\f
;;;; accessor/setter functions
+(eval-when (:compile-toplevel :execute)
+ (defparameter *specialized-array-element-types*
+ '(t
+ character
+ bit
+ (unsigned-byte 2)
+ (unsigned-byte 4)
+ (unsigned-byte 8)
+ (unsigned-byte 16)
+ (unsigned-byte 32)
+ (signed-byte 8)
+ (signed-byte 16)
+ (signed-byte 30)
+ (signed-byte 32)
+ single-float
+ double-float
+ #!+long-float long-float
+ (complex single-float)
+ (complex double-float)
+ #!+long-float (complex long-float))))
+
(defun hairy-data-vector-ref (array index)
(with-array-data ((vector array) (index index) (end))
(declare (ignore end) (optimize (safety 3)))
- (macrolet ((dispatch (&rest stuff)
- `(etypecase vector
- ,@(mapcar #'(lambda (type)
- (let ((atype `(simple-array ,type (*))))
- `(,atype
- (data-vector-ref (the ,atype vector)
- index))))
- stuff))))
- (dispatch
- t
- bit
- character
- (unsigned-byte 2)
- (unsigned-byte 4)
- (unsigned-byte 8)
- (unsigned-byte 16)
- (unsigned-byte 32)
- (signed-byte 8)
- (signed-byte 16)
- (signed-byte 30)
- (signed-byte 32)
- single-float
- double-float
- #!+long-float long-float
- (complex single-float)
- (complex double-float)
- #!+long-float (complex long-float)))))
+ (etypecase vector .
+ #.(mapcar (lambda (type)
+ (let ((atype `(simple-array ,type (*))))
+ `(,atype
+ (data-vector-ref (the ,atype vector)
+ index))))
+ *specialized-array-element-types*))))
(defun hairy-data-vector-set (array index new-value)
(with-array-data ((vector array) (index index) (end))
(declare (ignore end) (optimize (safety 3)))
- (macrolet ((dispatch (&rest stuff)
- `(etypecase vector
- ,@(mapcar #'(lambda (type)
- (let ((atype `(simple-array ,type (*))))
- `(,atype
- (data-vector-set (the ,atype vector)
- index
- (the ,type
- new-value)))))
- stuff))))
- (dispatch
- t
- bit
- character
- (unsigned-byte 2)
- (unsigned-byte 4)
- (unsigned-byte 8)
- (unsigned-byte 16)
- (unsigned-byte 32)
- (signed-byte 8)
- (signed-byte 16)
- (signed-byte 30)
- (signed-byte 32)
- single-float
- double-float
- #!+long-float long-float
- (complex single-float)
- (complex double-float)
- #!+long-float (complex long-float)))))
+ (etypecase vector .
+ #.(mapcar (lambda (type)
+ (let ((atype `(simple-array ,type (*))))
+ `(,atype
+ (data-vector-set (the ,atype vector)
+ index
+ (the ,type
+ new-value)))))
+ *specialized-array-element-types*))))
(defun %array-row-major-index (array subscripts
&optional (invalid-index-error-p t))
(list subscripts))
(let ((rank (array-rank array)))
(unless (= rank (length subscripts))
- (error "Wrong number of subscripts, ~D, for array of rank ~D"
+ (error "wrong number of subscripts, ~D, for array of rank ~D"
(length subscripts) rank))
(if (array-header-p array)
(do ((subs (nreverse subscripts) (cdr subs))
(declare (fixnum index dim))
(unless (< -1 index dim)
(if invalid-index-error-p
- (error "Invalid index ~D~[~;~:; on axis ~:*~D~] in ~S"
+ (error "invalid index ~D~[~;~:; on axis ~:*~D~] in ~S"
index axis array)
(return-from %array-row-major-index nil)))
(incf result (* chunk-size index))
(let ((index (first subscripts)))
(unless (< -1 index (length (the (simple-array * (*)) array)))
(if invalid-index-error-p
- (error "Invalid index ~D in ~S" index array)
+ (error "invalid index ~D in ~S" index array)
(return-from %array-row-major-index nil)))
index))))
(error "Vector axis is not zero: ~S" axis-number))
(length (the (simple-array * (*)) array)))
((>= axis-number (%array-rank array))
- (error "~D is too big; ~S only has ~D dimension~:P"
+ (error "~D is too big; ~S only has ~D dimension~:P."
axis-number array (%array-rank array)))
(t
(%array-dimension array axis-number))))
(defun array-has-fill-pointer-p (array)
#!+sb-doc
- "Returns T if the given Array has a fill pointer, or Nil otherwise."
+ "Return T if the given ARRAY has a fill pointer, or NIL otherwise."
(declare (array array))
(and (array-header-p array) (%array-fill-pointer-p array)))
(defun fill-pointer (vector)
#!+sb-doc
- "Returns the Fill-Pointer of the given Vector."
+ "Return the FILL-POINTER of the given VECTOR."
(declare (vector vector))
(if (and (array-header-p vector) (%array-fill-pointer-p vector))
(%array-fill-pointer vector)
(declare (vector vector) (fixnum new))
(if (and (array-header-p vector) (%array-fill-pointer-p vector))
(if (> new (%array-available-elements vector))
- (error "New fill pointer, ~S, is larger than the length of the vector."
- new)
+ (error
+ "The new fill pointer, ~S, is larger than the length of the vector."
+ new)
(setf (%array-fill-pointer vector) new))
(error 'simple-type-error
:datum vector
(defun vector-push (new-el array)
#!+sb-doc
- "Attempts to set the element of Array designated by the fill pointer
- to New-El and increment fill pointer by one. If the fill pointer is
- too large, Nil is returned, otherwise the index of the pushed element is
+ "Attempt to set the element of ARRAY designated by its fill pointer
+ to NEW-EL, and increment the fill pointer by one. If the fill pointer is
+ too large, NIL is returned, otherwise the index of the pushed element is
returned."
(declare (vector array))
(let ((fill-pointer (fill-pointer array)))
(setf (%array-fill-pointer array) (1+ fill-pointer))
fill-pointer))))
-(defun vector-push-extend (new-el array &optional
- (extension (if (zerop (length array))
- 1
- (length array))))
+(defun vector-push-extend (new-element
+ vector
+ &optional
+ (extension (1+ (length vector))))
#!+sb-doc
- "Like Vector-Push except that if the fill pointer gets too large, the
- Array is extended rather than Nil being returned."
- (declare (vector array) (fixnum extension))
- (let ((fill-pointer (fill-pointer array)))
+ "This is like Vector-Push except that if the fill pointer gets too
+ large, the Vector is extended rather than Nil being returned."
+ (declare (vector vector) (fixnum extension))
+ (let ((fill-pointer (fill-pointer vector)))
(declare (fixnum fill-pointer))
- (when (= fill-pointer (%array-available-elements array))
- (adjust-array array (+ fill-pointer extension)))
- (setf (aref array fill-pointer) new-el)
- (setf (%array-fill-pointer array) (1+ fill-pointer))
+ (when (= fill-pointer (%array-available-elements vector))
+ (adjust-array vector (+ fill-pointer extension)))
+ (setf (aref vector fill-pointer) new-element)
+ (setf (%array-fill-pointer vector) (1+ fill-pointer))
fill-pointer))
(defun vector-pop (array)
(let ((fill-pointer (fill-pointer array)))
(declare (fixnum fill-pointer))
(if (zerop fill-pointer)
- (error "Nothing left to pop.")
+ (error "There is nothing left to pop.")
(aref array
(setf (%array-fill-pointer array)
(1- fill-pointer))))))
(let ((dimensions (if (listp dimensions) dimensions (list dimensions))))
(cond ((/= (the fixnum (length (the list dimensions)))
(the fixnum (array-rank array)))
- (error "Number of dimensions not equal to rank of array."))
+ (error "The number of dimensions not equal to rank of array."))
((not (subtypep element-type (array-element-type array)))
- (error "New element type, ~S, is incompatible with old."
+ (error "The new element type, ~S, is incompatible with old type."
element-type)))
(let ((array-rank (length (the list dimensions))))
(declare (fixnum array-rank))
(when (and fill-pointer (> array-rank 1))
(error "Multidimensional arrays can't have fill pointers."))
(cond (initial-contents
- ;; Array former contents replaced by initial-contents.
+ ;; array former contents replaced by INITIAL-CONTENTS
(if (or initial-element-p displaced-to)
- (error "Initial contents may not be specified with ~
- the :initial-element or :displaced-to option."))
+ (error "INITIAL-CONTENTS may not be specified with ~
+ the :INITIAL-ELEMENT or :DISPLACED-TO option."))
(let* ((array-size (apply #'* dimensions))
(array-data (data-vector-from-inits
dimensions array-size element-type
fill-pointer)
0 dimensions nil)
(if (array-header-p array)
- ;; Simple multidimensional or single dimensional array.
+ ;; simple multidimensional or single dimensional array
(make-array dimensions
:element-type element-type
:initial-contents initial-contents)
array-data))))
(displaced-to
- ;; No initial-contents supplied is already established.
+ ;; We already established that no INITIAL-CONTENTS was supplied.
(when initial-element
- (error "The :initial-element option may not be specified ~
- with :displaced-to."))
+ (error "The :INITIAL-ELEMENT option may not be specified ~
+ with :DISPLACED-TO."))
(unless (subtypep element-type (array-element-type displaced-to))
- (error "One can't displace an array of type ~S into another of ~
- type ~S."
+ (error "can't displace an array of type ~S into another of ~
+ type ~S"
element-type (array-element-type displaced-to)))
(let ((displacement (or displaced-index-offset 0))
(array-size (apply #'* dimensions)))
(declare (fixnum displacement array-size))
(if (< (the fixnum (array-total-size displaced-to))
(the fixnum (+ displacement array-size)))
- (error "The :displaced-to array is too small."))
+ (error "The :DISPLACED-TO array is too small."))
(if (adjustable-array-p array)
;; None of the original contents appear in adjusted array.
(set-array-header array displaced-to array-size
(get-new-fill-pointer array array-size
fill-pointer)
displacement dimensions t)
- ;; Simple multidimensional or single dimensional array.
+ ;; simple multidimensional or single dimensional array
(make-array dimensions
:element-type element-type
:displaced-to displaced-to
(cond ((not fill-pointer)
(when (array-has-fill-pointer-p old-array)
(when (> (%array-fill-pointer old-array) new-array-size)
- (error "Cannot adjust-array an array (~S) to a size (~S) that is ~
- smaller than its fill pointer (~S)."
+ (error "cannot ADJUST-ARRAY an array (~S) to a size (~S) that is ~
+ smaller than its fill pointer (~S)"
old-array new-array-size (fill-pointer old-array)))
(%array-fill-pointer old-array)))
((not (array-has-fill-pointer-p old-array))
- (error "Cannot supply a non-NIL value (~S) for :fill-pointer ~
- in adjust-array unless the array (~S) was originally ~
- created with a fill pointer."
- fill-pointer
- old-array))
+ (error "cannot supply a non-NIL value (~S) for :FILL-POINTER ~
+ in ADJUST-ARRAY unless the array (~S) was originally ~
+ created with a fill pointer"
+ fill-pointer
+ old-array))
((numberp fill-pointer)
(when (> fill-pointer new-array-size)
- (error "Cannot supply a value for :fill-pointer (~S) that is larger ~
+ (error "can't supply a value for :FILL-POINTER (~S) that is larger ~
than the new length of the vector (~S)."
fill-pointer new-array-size))
fill-pointer)
((eq fill-pointer t)
new-array-size)
(t
- (error "Bogus value for :fill-pointer in adjust-array: ~S"
+ (error "bogus value for :FILL-POINTER in ADJUST-ARRAY: ~S"
fill-pointer))))
-(defun shrink-vector (vector new-size)
+(defun shrink-vector (vector new-length)
#!+sb-doc
- "Destructively alters the Vector, changing its length to New-Size, which
- must be less than or equal to its current size."
+ "Destructively alter VECTOR, changing its length to NEW-LENGTH, which
+ must be less than or equal to its current length."
(declare (vector vector))
(unless (array-header-p vector)
(macrolet ((frob (name &rest things)
`(,(car thing)
(fill (truly-the ,(car thing) ,name)
,(cadr thing)
- :start new-size)))
+ :start new-length)))
things))))
(frob vector
(simple-vector 0)
(coerce 0 '(complex long-float))))))
;; Only arrays have fill-pointers, but vectors have their length
;; parameter in the same place.
- (setf (%array-fill-pointer vector) new-size)
+ (setf (%array-fill-pointer vector) new-length)
vector)
(defun set-array-header (array data length fill-pointer displacement dimensions
\f
;;;; ZAP-ARRAY-DATA for ADJUST-ARRAY
-;;; Make a temporary to be used when old-data and new-data are EQ.
+;;; a temporary to be used when OLD-DATA and NEW-DATA are EQ.
;;; KLUDGE: Boy, DYNAMIC-EXTENT would be nice.
(defvar *zap-array-data-temp* (make-array 1000 :initial-element t))
(make-array length :initial-element t)))
(when initial-element-p
(unless (typep initial-element element-type)
- (error "~S cannot be used to initialize an array of type ~S."
+ (error "~S can't be used to initialize an array of type ~S."
initial-element element-type))
(fill (the simple-vector *zap-array-data-temp*) initial-element
:end length))
*zap-array-data-temp*)
-;;; This does the grinding work for ADJUST-ARRAY. It zaps the data from the
-;;; Old-Data in an arrangement specified by the Old-Dims to the New-Data in an
-;;; arrangement specified by the New-Dims. Offset is a displaced offset to be
-;;; added to computed indexes of Old-Data. New-Length, Element-Type,
-;;; Initial-Element, and Initial-Element-P are used when Old-Data and New-Data
-;;; are EQ; in this case, a temporary must be used and filled appropriately.
-;;; When Old-Data and New-Data are not EQ, New-Data has already been filled
-;;; with any specified initial-element.
+;;; This does the grinding work for ADJUST-ARRAY. It zaps the data
+;;; from the OLD-DATA in an arrangement specified by the OLD-DIMS to
+;;; the NEW-DATA in an arrangement specified by the NEW-DIMS. OFFSET
+;;; is a displaced offset to be added to computed indices of OLD-DATA.
+;;; NEW-LENGTH, ELEMENT-TYPE, INITIAL-ELEMENT, and INITIAL-ELEMENT-P
+;;; are used when OLD-DATA and NEW-DATA are EQ; in this case, a
+;;; temporary must be used and filled appropriately. When OLD-DATA and
+;;; NEW-DATA are not EQ, NEW-DATA has already been filled with any
+;;; specified initial-element.
(defun zap-array-data (old-data old-dims offset new-data new-dims new-length
element-type initial-element initial-element-p)
(declare (list old-dims new-dims))
offset)))))))
;;; Figure out the row-major-order index of an array reference from a
-;;; list of subscripts and a list of dimensions. This is for internal calls
-;;; only, and the subscripts and dim-list variables are assumed to be reversed
-;;; from what the user supplied.
+;;; list of subscripts and a list of dimensions. This is for internal
+;;; calls only, and the subscripts and dim-list variables are assumed
+;;; to be reversed from what the user supplied.
(defun row-major-index-from-dims (rev-subscripts rev-dim-list)
(do ((rev-subscripts rev-subscripts (cdr rev-subscripts))
(rev-dim-list rev-dim-list (cdr rev-dim-list))
(t
(unless (bit-array-same-dimensions-p bit-array-1
result-bit-array)
- (error "~S and ~S do not have the same dimensions."
+ (error "~S and ~S don't have the same dimensions."
bit-array-1 result-bit-array))
result-bit-array)))
(declare (type (array bit) bit-array-1 bit-array-2)
(type (or (array bit) (member t nil)) result-bit-array))
(unless (bit-array-same-dimensions-p bit-array-1 bit-array-2)
- (error "~S and ~S do not have the same dimensions."
+ (error "~S and ~S don't have the same dimensions."
bit-array-1 bit-array-2))
(let ((result-bit-array (pick-result-array result-bit-array bit-array-1)))
(if (and (simple-bit-vector-p bit-array-1)