;;; -*- Mode:LISP; Package:USER; Base:10; Readtable:CL -*- (defsubst make-bit-string (size) (global::make-array size :type art-1b)) (defsubst bit-string-size (b) (length b)) (defun with-bit-string-destination (source receiver) (let ((size (length source))) (funcall receiver (make-bit-string size) size))) (defun for-bits-in-bit-string (b receiver) (dotimes (index (bit-string-size b)) (funcall receiver index (elt b index)))) (defun mirror-bit-string (b) (with-bit-string-destination b #'(lambda (dest size) (dotimes (i size) (setf (elt dest i) (elt b (- size i 1)))) dest))) (defun rotate-bit-string (b distance) (with-bit-string-destination b #'(lambda (dest-string size) (let* ((rotation (remainder distance size)) (real-rot (if (minusp rotation) (+ rotation size) rotation))) (copy-array-portion b 0 (- size real-rot) dest-string real-rot size) (copy-array-portion b (- size real-rot) size dest-string 0 real-rot)) dest-string))) (defun ldb-from-bit-string (byte string) (let* ((destination-size (byte-size byte)) (source-pos (byte-position byte)) (destination-string (make-bit-string destination-size))) (copy-array-portion string source-pos (+ source-pos destination-size) destination-string 0 destination-size) destination-string)) (defun concat-two-bit-strings (lsb msb) (let* ((l-size (bit-string-size lsb)) (m-size (bit-string-size msb)) (total-size (+ l-size m-size)) (dest (make-bit-string total-size))) (copy-array-portion lsb 0 l-size dest 0 l-size) (copy-array-portion msb 0 m-size dest l-size total-size) dest)) (deff concat-bit-strings (binary-function->left-associating-lexpr #'concat-two-bit-strings #*)) (defun %%boxed->bit-string (byte) #'(lambda (frob) (let ((b (make-bit-string (byte-size byte)))) (%p-dpb-offset frob byte b 1) b))) (defun %%bit-string->boxed (byte type) #'(lambda (b) (let ((f (ncons nil))) (%p-store-tag-and-pointer f type (%p-ldb-offset byte b 1)) (car f)))) (deff %fixnum->bit-string (%%boxed->bit-string %%q-pointer)) (deff %char->bit-string (%%boxed->bit-string %%ch-char)) (deff %bit-string->fixnum (%%bit-string->boxed %%q-pointer dtp-fix)) (deff %bit-string->char (%%bit-string->boxed %%ch-char dtp-character)) (defun bit-string->fixnum (b) (%bit-string->fixnum (concat-bit-strings b (make-bit-string (byte-size %%q-pointer))))) (defun fixnum->bit-string (f &optional (size (max (integer-length f) 24.))) (let ((f f) (bs (make-bit-string (max size 24.))) bit) (dotimes (i size) (multiple-value-setq (f bit) (floor f 2.)) (setf (elt bs i) bit)) bs)) (defun bit-string->fixnum (bs) (let ((n 0) (s (length bs))) (tagbody loop (if (zerop s) (return-from bit-string->fixnum n)) (setq s (1- s)) (setq n (+ (ash n 1.) (elt bs s))) (go loop))))