Loading macro-utils.lisp +46 −0 Original line number Diff line number Diff line Loading @@ -35,3 +35,49 @@ collect (subseq docstring start pos) into words finally (return (format nil "~{~<~%~1,76:;~A~>~^ ~}" words)))) (defun ref-form (vector-name index-name byte-size signedp big-endian-p) "Return a form that fetches a SIGNEDP BYTE-SIZE value from VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P." (multiple-value-bind (low high increment compare) (if big-endian-p (values 0 (1- byte-size) 1 #'>) (values (1- byte-size) 0 -1 #'<)) (do ((i (+ low increment) (+ i increment)) (shift (* (- byte-size 2) 8) (- shift 8)) (forms nil)) ((funcall compare i high) `(let* ((high-byte (aref , vector-name (+ ,index-name ,low))) ;; Would be great if we could just sign-extend along ;; with the load, but this is as good as it gets in ;; portable Common Lisp. (signed-high ,(if signedp `(if (logbitp 7 high-byte) (- high-byte 256) high-byte) 'high-byte)) (shifted-into-place (ash signed-high ,(* (1- byte-size) 8)))) (declare (type (unsigned-byte 8) high-byte)) (declare (type (,(if signedp 'signed-byte 'unsigned-byte) 8) signed-high)) (logior shifted-into-place ,@(nreverse forms)))) (push `(ash (aref ,vector-name (+ ,index-name ,i)) ,shift) forms)))) (defun set-form (vector-name index-name value-name byte-size big-endian-p) "Return a form that stores a BYTE-SIZE VALUE-NAME into VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P. The form returns VALUE-NAME." `(progn ,@(loop for i from 1 to byte-size collect (let ((offset (if big-endian-p (- byte-size i) (1- i)))) `(setf (aref ,vector-name (+ ,index-name ,offset)) (ldb (byte 8 ,(* 8 (1- i))) ,value-name)))) ,value-name)) vectors.lisp +0 −48 Original line number Diff line number Diff line Loading @@ -14,54 +14,6 @@ #-(or sbcl cmu) (values v start (or end (length v)))) (eval-when (:compile-toplevel :execute) (defun ref-form (vector-name index-name byte-size signedp big-endian-p) "Return a form that fetches a SIGNEDP BYTE-SIZE value from VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P." (multiple-value-bind (low high increment compare) (if big-endian-p (values 0 (1- byte-size) 1 #'>) (values (1- byte-size) 0 -1 #'<)) (do ((i (+ low increment) (+ i increment)) (shift (* (- byte-size 2) 8) (- shift 8)) (forms nil)) ((funcall compare i high) `(let* ((high-byte (aref , vector-name (+ ,index-name ,low))) ;; Would be great if we could just sign-extend along ;; with the load, but this is as good as it gets in ;; portable Common Lisp. (signed-high ,(if signedp `(if (logbitp 7 high-byte) (- high-byte 256) high-byte) 'high-byte)) (shifted-into-place (ash signed-high ,(* (1- byte-size) 8)))) (declare (type (unsigned-byte 8) high-byte)) (declare (type (,(if signedp 'signed-byte 'unsigned-byte) 8) signed-high)) (logior shifted-into-place ,@(nreverse forms)))) (push `(ash (aref ,vector-name (+ ,index-name ,i)) ,shift) forms)))) (defun set-form (vector-name index-name value-name byte-size big-endian-p) "Return a form that stores a BYTE-SIZE VALUE-NAME into VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P. The form returns VALUE-NAME." `(progn ,@(loop for i from 1 to byte-size collect (let ((offset (if big-endian-p (- byte-size i) (1- i)))) `(setf (aref ,vector-name (+ ,index-name ,offset)) (ldb (byte 8 ,(* 8 (1- i))) ,value-name)))) ,value-name)) ) ; EVAL-WHEN (macrolet ((define-fetcher (bitsize signedp big-endian-p) (let ((ref-name (byte-ref-fun-name bitsize signedp big-endian-p)) (bytes (truncate bitsize 8))) Loading Loading
macro-utils.lisp +46 −0 Original line number Diff line number Diff line Loading @@ -35,3 +35,49 @@ collect (subseq docstring start pos) into words finally (return (format nil "~{~<~%~1,76:;~A~>~^ ~}" words)))) (defun ref-form (vector-name index-name byte-size signedp big-endian-p) "Return a form that fetches a SIGNEDP BYTE-SIZE value from VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P." (multiple-value-bind (low high increment compare) (if big-endian-p (values 0 (1- byte-size) 1 #'>) (values (1- byte-size) 0 -1 #'<)) (do ((i (+ low increment) (+ i increment)) (shift (* (- byte-size 2) 8) (- shift 8)) (forms nil)) ((funcall compare i high) `(let* ((high-byte (aref , vector-name (+ ,index-name ,low))) ;; Would be great if we could just sign-extend along ;; with the load, but this is as good as it gets in ;; portable Common Lisp. (signed-high ,(if signedp `(if (logbitp 7 high-byte) (- high-byte 256) high-byte) 'high-byte)) (shifted-into-place (ash signed-high ,(* (1- byte-size) 8)))) (declare (type (unsigned-byte 8) high-byte)) (declare (type (,(if signedp 'signed-byte 'unsigned-byte) 8) signed-high)) (logior shifted-into-place ,@(nreverse forms)))) (push `(ash (aref ,vector-name (+ ,index-name ,i)) ,shift) forms)))) (defun set-form (vector-name index-name value-name byte-size big-endian-p) "Return a form that stores a BYTE-SIZE VALUE-NAME into VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P. The form returns VALUE-NAME." `(progn ,@(loop for i from 1 to byte-size collect (let ((offset (if big-endian-p (- byte-size i) (1- i)))) `(setf (aref ,vector-name (+ ,index-name ,offset)) (ldb (byte 8 ,(* 8 (1- i))) ,value-name)))) ,value-name))
vectors.lisp +0 −48 Original line number Diff line number Diff line Loading @@ -14,54 +14,6 @@ #-(or sbcl cmu) (values v start (or end (length v)))) (eval-when (:compile-toplevel :execute) (defun ref-form (vector-name index-name byte-size signedp big-endian-p) "Return a form that fetches a SIGNEDP BYTE-SIZE value from VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P." (multiple-value-bind (low high increment compare) (if big-endian-p (values 0 (1- byte-size) 1 #'>) (values (1- byte-size) 0 -1 #'<)) (do ((i (+ low increment) (+ i increment)) (shift (* (- byte-size 2) 8) (- shift 8)) (forms nil)) ((funcall compare i high) `(let* ((high-byte (aref , vector-name (+ ,index-name ,low))) ;; Would be great if we could just sign-extend along ;; with the load, but this is as good as it gets in ;; portable Common Lisp. (signed-high ,(if signedp `(if (logbitp 7 high-byte) (- high-byte 256) high-byte) 'high-byte)) (shifted-into-place (ash signed-high ,(* (1- byte-size) 8)))) (declare (type (unsigned-byte 8) high-byte)) (declare (type (,(if signedp 'signed-byte 'unsigned-byte) 8) signed-high)) (logior shifted-into-place ,@(nreverse forms)))) (push `(ash (aref ,vector-name (+ ,index-name ,i)) ,shift) forms)))) (defun set-form (vector-name index-name value-name byte-size big-endian-p) "Return a form that stores a BYTE-SIZE VALUE-NAME into VECTOR-NAME, starting at INDEX-NAME. The value is stored in the vector according to BIG-ENDIAN-P. The form returns VALUE-NAME." `(progn ,@(loop for i from 1 to byte-size collect (let ((offset (if big-endian-p (- byte-size i) (1- i)))) `(setf (aref ,vector-name (+ ,index-name ,offset)) (ldb (byte 8 ,(* 8 (1- i))) ,value-name)))) ,value-name)) ) ; EVAL-WHEN (macrolet ((define-fetcher (bitsize signedp big-endian-p) (let ((ref-name (byte-ref-fun-name bitsize signedp big-endian-p)) (bytes (truncate bitsize 8))) Loading