52 lines
2.1 KiB
Plaintext
52 lines
2.1 KiB
Plaintext
;;;; The bit operators on dyn ints, beside the same operations on typed i64:
|
|
;;;; each line prints the dyn answer, the typed one, and whether they agree.
|
|
;;;; A dyn int is an i64, so the two must be the same number for every count
|
|
;;;; in 0..63. With an argument, the program traps instead: 1 a shift count
|
|
;;;; out of range, 2 a bool operand, 3 a float operand, 4 a negative count to >>.
|
|
|
|
(defn dyn-ops [a b n] dyn
|
|
[(bit-and a b) (bit-or a b) (bit-xor a b) (bit-not a) (<< a n) (>> a n)
|
|
(rotate-left a n) (rotate-right a n) (popcount a) (leading-zeros a)
|
|
(trailing-zeros a) (bit-xor a b n) (&& a b) (|| a b)])
|
|
|
|
(defn typed-ops [a i64 b i64 n i64] [14 i64]
|
|
[(bit-and a b) (bit-or a b) (bit-xor a b) (bit-not a) (<< a n) (>> a n)
|
|
(rotate-left a n) (rotate-right a n) (popcount a) (leading-zeros a)
|
|
(trailing-zeros a) (bit-xor a b n) (&& a b) (|| a b)])
|
|
|
|
(defn compare [a i64 b i64 n i64] ()
|
|
(let [d (dyn-ops a b n)
|
|
t (typed-ops a b n)]
|
|
(dotimes [i 14]
|
|
(print (at d i) " ")
|
|
(when (!= (i64 (at d i)) (at t i))
|
|
(print "DIFFER at " i " typed " (at t i) " ")))
|
|
(println)))
|
|
|
|
;; A typed operand beside a dyn one makes the whole operation dyn.
|
|
(defonce mask i32 255)
|
|
(defn mixed [x] dyn (bit-and x mask))
|
|
|
|
(defn shift [a n] dyn (<< a n))
|
|
(defn sar [a n] dyn (>> a n))
|
|
(defn band [a b] dyn (bit-and a b))
|
|
|
|
(defn main [args [str]] i32
|
|
(let [k (if (> (length args) 1) (bytes->i64 (bytes-view (at args 1))) 0)]
|
|
(cond
|
|
(= k 0)
|
|
(do
|
|
(compare 0 0 0)
|
|
(compare -1 12345 63)
|
|
(compare -9000000000000000000 1234567890123 13)
|
|
(compare 9223372036854775807 -9223372036854775807 1)
|
|
(compare 281474976710656 -281474976710657 47)
|
|
(compare 1 3 62)
|
|
(println (mixed 4660) (mixed -1))
|
|
(println (leading-zeros 0) (trailing-zeros 0) (popcount -1))
|
|
0)
|
|
(= k 1) (do (println "before") (println (shift 1 64)) 0)
|
|
(= k 2) (do (println "before") (println (band true 1)) 0)
|
|
(= k 3) (do (println "before") (println (band 1.5 1)) 0)
|
|
:else (do (println "before") (println (sar 1 -1)) 0))))
|