(module binary mzscheme
  (require "list.ss")
  (provide (all-defined))

  ;; binary

  (define (bitmask bits)
    (- (arithmetic-shift 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))  ;; scheme's ints are 2-adic


  (define (bit address n)
    (bitwise-and 1 (>>> address n)))

  ;; convert anything that might be passed to the assembler
  ;; representing a number to integer

  (define (int x)
    (cond
     ((number? x) (inexact->exact (round x)))
     (else (raise `(cannot-convert-to-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)) ;; all bits
  (define (flip    b)  (bxor b 1))  ;; one bit

  (define (negate x) (* -1 x))



  ;; symbol generation. not going to make a separate module for this...
  (define (generated-label? x)
    (and (symbol? x)
         (let ((chars
                (string->list
                 (symbol->string x))))
           (if (eq? #\L (car chars))
               (string->number
                (list->string (cdr chars)))
               #f))))
    
  (define make-label
    (let ((n -1))
      (lambda ()
        (set! n (+ n 1))
        (string->symbol
         (format "L~s" n)))))
  

)