64 lines
2.4 KiB
Plaintext
64 lines
2.4 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, with "dyn" a dyn char below zero does, and
|
|
;;;; with "u64" a char plus the largest u64 does rather than wrapping round,
|
|
;;;; and with "i64" and "dyn-i64" a char plus the largest i64 does, naming it.
|
|
|
|
(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))
|
|
;; A char minus a char where an integer is wanted is that integer.
|
|
(defn digit [c char] i32 (- c \0))
|
|
(defn gap [a char b char] u8 (- a b))
|
|
(defn gaps [a char b char] i32
|
|
(let [v (vec-new i32)]
|
|
(push v (- a b))
|
|
(+ (- a b) (at v 0) 1)))
|
|
(defn plus-u64 [c char n u64] char (+ c n))
|
|
(defn plus-i64 [c char n i64] char (+ c n))
|
|
|
|
(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 \é))
|
|
(println (digit \7) (gap \c \a) (gaps \c \a) (plus-u64 \a (u64 2)))
|
|
;; Longer chains fold left, each step by its own operands.
|
|
(println (- \z \a 1) (+ 1 2 \a) (- \z 1 \a))
|
|
;; += 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)))
|
|
(= (at args 1) "u64")
|
|
(println (plus-u64 \a (- (u64 0) (u64 (- k 1)))))
|
|
(= (at args 1) "i64")
|
|
(println (plus-i64 \a (- (max-value i64) (i64 (- k 2)))))
|
|
(= (at args 1) "dyn-i64")
|
|
(println (add \a (- (max-value i64) (i64 (- k 2)))))
|
|
:else
|
|
(println (sub \a (* k 100))))))
|
|
0)
|