flan/test/programs/bits-dyn.flan

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