#lang scheme/base
(require
(lib "match.ss")
"list.ss"
"tree.ss")
(require (lib "78.ss" "srfi"))
(check-set-mode! 'report-failed)
(provide
(all-defined-out))
(define (sign-extender n)
(lambda (x) (sign-extend x n)))
(define (sign-extend x n)
(let ((signmask (<<< 1 (- n 1))))
(- (bxor signmask
(band x (bitmask n)))
signmask)))
(define (bit? n bit)
(let ((mask (<<< 1 bit)))
(= (band n mask) mask)))
(define (bitmask bits)
(- (<<< 1 bits) 1))
(define (make-mask bits)
(let ((bm (bitmask bits)))
(lambda (x) (bitwise-and bm x))))
(define <<< arithmetic-shift)
(define (>>> val shift)
(<<< val (* -1 shift)))
(define (<< x) (<<< x 1))
(define (2/ x) (>>> x 1)) (define 2* <<)
(define (bit address n)
(bitwise-and 1 (>>> address n)))
(define (bit-floor n bits) (band n (bxor -1 (bitmask bits))))
(define (bit-ceil n bits) (+ (bit-floor (- n 1) bits) (<<< 1 bits)))
(define (block-floor n bits) (>>> n bits))
(define (block-ceil n bits) (>>> (bit-ceil n bits) bits))
(define (int x)
(cond
((number? x) (inexact->exact (round x)))
(else (error 'cannot-convert-to-int "~a" x))))
(define (int8 x)
(bitwise-and #xFF (int x)))
(define (band x y) (bitwise-and (int x) (int y)))
(define (bior x y) (bitwise-ior (int x) (int y)))
(define (bxor x y) (bitwise-xor (int x) (int y)))
(define (invert b) (bxor b -1)) (define (flip b) (bxor b 1))
(define (negate x) (* -1 x))
(define (ceiling-block address blocksize)
(+ 1 (floor (/ (- address 1) blocksize))))
(define (chunk-size-list initial max)
(let next ((total initial))
(if (> total max)
(cons max (next (- total max)))
(list total))))
(check (chunk-size-list 13 4) => '(4 4 4 1))
(define (split-nibble-list lst left right)
(unless (or (zero? left) (zero? right))
(error 'split-nibble-list-need-zero))
(let ((mask (make-mask (max left right))))
(flatten
(map
(lambda (x)
(list (mask (>>> x left))
(mask (>>> x right))))
lst))))
(check (split-nibble-list '(#x102 #xFFAA) 0 8)
=> '(#x02 #x01 #xAA #xFF))
(define (join-nibble-list lst left right)
(if (= 1 (bitwise-and 1 (length lst)))
(error 'odd-list-length "join-nibble-list: odd list length: ~a" lst)
(let
((mask
(make-mask (max left right)))
(select
(lambda (lst which)
(let rest ((l lst))
(if (null? l) l
(cons (which l)
(rest (cddr l))))))))
(map
(lambda (l r)
(bior (<<< (mask l) left)
(<<< (mask r) right)))
(select lst first)
(select lst second)))))
(check (join-nibble-list '(#x01 #x02 #x03 #x04) 0 8)
=> '(#x201 #x403))
(define (list->table lst size)
(let next ((in lst)
(out '())
(current '(0)))
(match (cons in current)
((() 0) (reverse out)) ((_ n . l)
(if (or (null? in)
(= n size))
(next in
(cons (reverse l) out)
'(0))
(next (cdr in)
out
(cons (+ 1 n)
(cons (car in) l))))))))
(check (list->table '(1 2 3 4 5) 2)
=> '((1 2) (3 4) (5)))
(define (->byte-list x)
(cond
((string? x) (->byte-list (string->bytes/utf-8 x)))
((bytes? x) (bytes->list x))
((list? x) x)
(else (error 'byte-list "~a" x))))