;;;; 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))))