;;;; Char arithmetic (decision 131, Kotlin's rules): a char plus or minus an ;;;; integer is a char, an integer plus a char is too, and a char minus a char ;;;; is the distance, an i32. Dyn chars do the same. Byte code beside it is ;;;; unchanged. With "past" a char past U+10FFFF traps, with "surrogate" one ;;;; landing on a surrogate does, and with "dyn" a dyn char below zero does. (defn show [x] () (println x)) (defn add [a b] dyn (+ a b)) (defn sub [a b] dyn (- a b)) (defn upper [c char] char (if (and (>= c \a) (<= c \z)) (- c 32) c)) (defn main [args [str]] i32 ;; The fork case with arithmetic: a let-bound char stays a char. (let [c \a] (show c) (show (+ c 1))) ;; Each rule, typed. (let [c (char 100) n 3] (println (+ c n) (+ n c) (- c n) (- c \a) (- \a \A) (+ \a 1 1))) (println (upper \q) (upper \Q) (upper \é)) ;; += and -= on a char local. (let [c \a] (set c (+ c 2)) (set c (- c 1)) (println c)) ;; Dyn chars follow the same rules. (println (add \a 1) (add 1 \a) (sub \z 1) (sub \a \A) (add (char 120) (the dyn 2))) ;; Byte code: a char difference where a byte is wanted is a byte. (let [b (u8 65) v (vec-new u8)] (push v (+ b (- \a \A))) (println (at v 0) (= (at v 0) \a))) (when (> (length args) 1) (let [k (length args)] (cond (= (at args 1) "past") (println (+ (char 0x10FFFF) (- k 1))) (= (at args 1) "surrogate") (println (+ (char 0xD7FF) (- k 1))) :else (println (sub \a (* k 100)))))) 0)