;;;; A dyn into a typed integer of every width: an int in the width's range ;;;; passes, and so does a char's code point where it fits (ASCII only into a ;;;; byte). A cast on a dyn is the typed cast after an unbox, so it takes a ;;;; char too and wraps as a typed cast does. With an argument, one crossing ;;;; out of range traps at its call. (defn to-i8 [x i8] i64 (i64 x)) (defn to-u8 [x u8] i64 (i64 x)) (defn to-i16 [x i16] i64 (i64 x)) (defn to-u16 [x u16] i64 (i64 x)) (defn to-i32 [x i32] i64 (i64 x)) (defn to-u32 [x u32] i64 (i64 x)) (defn to-i64 [x i64] i64 x) (defn to-u64 [x u64] u64 x) (defn d [x] dyn x) (defn main [args [str]] i32 (do ;; the edges of each width, both ends, and a char at each (println (to-i8 (d -128)) (to-i8 (d 127)) (to-i8 (d \a))) (println (to-u8 (d 0)) (to-u8 (d 255)) (to-u8 (d \a))) (println (to-i16 (d -32768)) (to-i16 (d 32767)) (to-i16 (d \é))) (println (to-u16 (d 0)) (to-u16 (d 65535)) (to-u16 (d \日))) (println (to-i32 (d -2147483648)) (to-i32 (d 2147483647)) (to-i32 (d \😀))) (println (to-u32 (d 0)) (to-u32 (d 4294967295)) (to-u32 (d \😀))) (println (to-i64 (d -9223372036854775807)) (to-i64 (d 9223372036854775807)) (to-i64 (d \😀))) (println (to-u64 (d 0)) (to-u64 (d 9223372036854775807)) (to-u64 (d \😀))) ;; casts: a char at every width, and the typed cast's wrap (println (i8 (d \a)) (u8 (d \a)) (i16 (d \a)) (u16 (d \a)) (i32 (d \a)) (u32 (d \a)) (i64 (d \a)) (u64 (d \a))) (println (u32 (d -1)) (u32 (the i64 -1)) (u8 (d 256)) (u8 (the i64 256))) ;; into a typed array and a struct, chars by the same rule (println (sum (d [\a \b])) (pair-sum (d {:a \a :b \日}))) (when (> (length args) 1) (let [w (at args 1)] (cond (= w "u8-256") (println (to-u8 (d 256))) (= w "u8-neg") (println (to-u8 (d -1))) (= w "i8-128") (println (to-i8 (d 128))) (= w "i16-big") (println (to-i16 (d 32768))) (= w "u16-big") (println (to-u16 (d 65536))) (= w "i32-big") (println (to-i32 (d 2147483648))) (= w "u32-neg") (println (to-u32 (d -1))) (= w "u64-neg") (println (to-u64 (d -1))) (= w "u8-char") (println (to-u8 (d \é))) (= w "u16-char") (println (to-u16 (d \😀))) (= w "float") (println (to-i64 (d 2.0))) (= w "elem-char") (println (bytes-sum (d [\a \é]))) (= w "field-char") (println (pair-sum (d {:a \é :b 1}))) :else (println (to-i64 (d "x"))))))) 0) (defn sum [xs [const i32]] i64 (let [t (the i64 0)] (dotimes [i (length xs)] (set t (+ t (i64 (at xs i))))) t)) (defn bytes-sum [xs [const u8]] i64 (let [t (the i64 0)] (dotimes [i (length xs)] (set t (+ t (i64 (at xs i))))) t)) (defstruct Pair [a u8 b i32]) (defn pair-sum [p Pair] i64 (+ (i64 (.a p)) (i64 (.b p))))