flan/test/programs/char.flan

59 lines
2.0 KiB
Plaintext

;;;; A typed char (decision 127): a char literal is a char unless typed code
;;;; wants a number, and a char crossing into dyn stays a char. It compares,
;;;; orders and hashes; (i32 c) and (char n) convert. With "dyn-int" a dyn
;;;; int at a char parameter traps, with "surrogate" (char n) does, and with
;;;; "u64" (char n) on a u64 past 2^63 does, naming the u64.
(defn show [x] () (println x))
(defn take-char [c char] char c)
(defn next-char [c char] char (char (+ (i32 c) 1)))
(defn a-dyn [x] dyn x)
(defn main [args [str]] i32
;; A direct literal and a let-bound one print alike through dyn.
(show \a)
(let [c \a] (show c))
;; Printed as its literal, as a dyn char is, alone and inside a value.
(let [e \é]
(println e [e \z \space])
(println (i32 e) (u32 e)))
;; Equality and ordering by code point.
(println (< \a \b) (= \a \a) (!= \a \b) (>= \é \z) (min \q \c) (max \q \c))
;; Conversions both ways.
(println (char 65) (char 0x1F600) (i32 \A) (u8 \A) (next-char \y))
(let [n 66] (println (char n)))
;; A map keyed by char.
(let [m (map-new char i32)]
(put m \x 1)
(put m \é 2)
(println (get m \x) (get m \é) (has-key m \y)))
;; A match over a char.
(let [k \b]
(println (match k \a 1 \b 2 _ 0)))
;; Byte code is unchanged: a literal beside a byte is the byte.
(let [b (u8 97)
v (vec-new u8)
s (string-new)]
(println (= b \a) (= \a b))
(push v \z)
(println (at v 0))
;; And a char appends to a String as its UTF-8.
(append s \é)
(append s (char 0x65E5))
(println s))
;; A dyn char into a typed char, and typed chars viewed from dyn.
(println (take-char (a-dyn \q)))
(let [cs [\x \y]]
(show cs)
(show (at (a-dyn cs) 1)))
(when (> (length args) 1)
(cond
(= (at args 1) "dyn-int") (println (take-char (a-dyn 97)))
(= (at args 1) "u64")
(let [n (+ (u64 9223372036854775807) (u64 (length args)))]
(println (char n)))
:else
(let [n (+ 0xD800 (length args))]
(println (char n)))))
0)