44 lines
1.5 KiB
Plaintext
44 lines
1.5 KiB
Plaintext
;;;; 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)
|