bitwise.scm 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Harald Glab-Phlak, Mike Sperber
  3. ; R6RS bitwise operations
  4. ; Taken from the R6RS document.
  5. (define (bitwise-if ei1 ei2 ei3)
  6. (bitwise-ior (bitwise-and ei1 ei2)
  7. (bitwise-and (bitwise-not ei1) ei3)))
  8. (define bitwise-arithmetic-shift arithmetic-shift)
  9. (define bitwise-arithmetic-shift-left bitwise-arithmetic-shift)
  10. (define (bitwise-arithmetic-shift-right ei1 ei2)
  11. (bitwise-arithmetic-shift ei1 (- ei2)))
  12. (define bitwise-bit-count bit-count)
  13. (define (bitwise-bit-set? ei1 ei2)
  14. (not (zero?
  15. (bitwise-and
  16. (bitwise-arithmetic-shift-left 1 ei2)
  17. ei1))))
  18. (define (bitwise-bit-field ei1 ei2 ei3)
  19. (let ((mask
  20. (bitwise-not
  21. (bitwise-arithmetic-shift-left -1 ei3))))
  22. (bitwise-arithmetic-shift-right
  23. (bitwise-and ei1 mask)
  24. ei2)))
  25. (define (bitwise-copy-bit ei1 ei2 ei3)
  26. (bitwise-if (bitwise-arithmetic-shift-left 1 ei2)
  27. (bitwise-arithmetic-shift-left ei3 ei2)
  28. ei1))
  29. (define (bitwise-copy-bit-field ei1 ei2 ei3 ei4)
  30. (bitwise-if (bitwise-and (bitwise-arithmetic-shift-left -1 ei2)
  31. (bitwise-not
  32. (bitwise-arithmetic-shift-left -1 ei3)))
  33. (bitwise-arithmetic-shift-left ei4 ei2)
  34. ei1))
  35. (define (bitwise-rotate-bit-field ei1 ei2 ei3 ei4)
  36. (let* ((n ei1)
  37. (start ei2)
  38. (end ei3)
  39. (count ei4)
  40. (width (- end start)))
  41. (if (positive? width)
  42. (let* ((count (remainder count width))
  43. (field0
  44. (bitwise-bit-field n start end))
  45. (field1 (bitwise-arithmetic-shift-left
  46. field0 count))
  47. (field2 (bitwise-arithmetic-shift-right
  48. field0
  49. (- width count)))
  50. (field (bitwise-ior field1 field2)))
  51. (bitwise-copy-bit-field n start end field))
  52. n)))
  53. (define (bitwise-reverse-bit-field ei1 ei2 ei3)
  54. (letrec* ((reverse-bit-field-recur
  55. (lambda (n1 n2 len)
  56. (if (> len 0)
  57. (reverse-bit-field-recur
  58. (bitwise-arithmetic-shift-right n1 1)
  59. (bitwise-copy-bit (bitwise-arithmetic-shift-left n2 1) 0 n1)
  60. (- len 1))
  61. n2))))
  62. (let ((width (- ei3 ei2)))
  63. (if (positive? width)
  64. (let ((field (bitwise-bit-field ei1 ei2 ei3)))
  65. (bitwise-copy-bit-field
  66. ei1 ei2 ei3 (reverse-bit-field-recur field 0 width)))
  67. ei1))))
  68. (define (bitwise-length ei)
  69. (do ((result 0 (+ result 1))
  70. (bits (if (negative? ei)
  71. (bitwise-not ei)
  72. ei)
  73. (bitwise-arithmetic-shift bits -1)))
  74. ((zero? bits)
  75. result)))
  76. (define (bitwise-first-bit-set ei)
  77. (cond ((eq? ei 0) -1)
  78. ((eq? (remainder ei 2) 1) 0)
  79. ((eq? (remainder ei 2) 0)
  80. (let loop ((num ei)
  81. (count 0))
  82. (if (or (eq? num 1)
  83. (eq? (remainder num 2) 1))
  84. count
  85. (loop (bitwise-arithmetic-shift-right num 1) (+ count 1)))))))