91 lines
3.1 KiB
Plaintext
91 lines
3.1 KiB
Plaintext
;;;; String: owned, growable, always valid UTF-8. Multi-byte append, insert
|
|
;;;; and remove by character position, iteration by runes, the byte length
|
|
;;;; beside the character count, a copy, printing inside a structure, and a
|
|
;;;; String crossing into dyn as a copy of its text.
|
|
|
|
(defstruct Named [label String n i32])
|
|
|
|
(defn as-dyn [d] dyn d)
|
|
|
|
(defn main [] i32
|
|
(let [s (string-new "héllo")]
|
|
(append s " wörld")
|
|
(append s 0x65e5) ; 日, three bytes
|
|
(append s \!)
|
|
(println s)
|
|
(println (length s) (rune-count s))
|
|
;; Positions are characters: 1 is after the h, whatever é takes.
|
|
(insert s 1 "→")
|
|
(insert s 0 0x1f600) ; four bytes at the front
|
|
(println s)
|
|
(println (remove s 2)) ; the → that was inserted, as a code point
|
|
(println (remove s 0)) ; the emoji
|
|
(println s)
|
|
;; Appending a String to itself reads the bytes it had before growing.
|
|
(let [t (string-new "ab")]
|
|
(append t t)
|
|
(append t t)
|
|
(println t (length t))
|
|
(free t))
|
|
;; Iteration by runes.
|
|
(let [it (runes s)
|
|
going true
|
|
n 0]
|
|
(while going
|
|
(match (runes-next (addr it))
|
|
(Some c) (do (when (> (i32 c) 127) (print (i32 c) "")) (set n (+ n 1)))
|
|
None (set going false)))
|
|
(println n))
|
|
;; A copy is independent of the original.
|
|
(let [c (clone s)]
|
|
(append c "?")
|
|
(println (length s) (length c))
|
|
(free c))
|
|
;; The str view and the byte view cost nothing.
|
|
(println (= (str s) "héllo wörld日!"))
|
|
(println (length (bytes-view s)))
|
|
;; Inside a structure it prints quoted, as a str field does.
|
|
(let [m (Named {.label (string-new "x") .n 3})]
|
|
(println m)
|
|
(free (.label m)))
|
|
;; Crossing into dyn copies the text, which the dyn side then owns.
|
|
(let [d (as-dyn s)]
|
|
(append s "tail")
|
|
(println d)
|
|
(println (type-of d)))
|
|
;; The builders answer Strings.
|
|
(let [j (join (slice [(bytes-view "a") (bytes-view "b")]) (bytes-view "-"))]
|
|
(println j)
|
|
(free j))
|
|
;; = and != compare bytes, against a String or a str, either side first.
|
|
(let [a (string-new "日本")
|
|
b (string-new "日")]
|
|
(append b 0x672c)
|
|
(println (= a b) (!= a b) (= a "日本") (= "日本" a) (= a "日") (!= b "x"))
|
|
(println (= a b (to-upper (bytes-view "日本"))))
|
|
(free a)
|
|
(free b))
|
|
;; bytes->string copies: a write through the Vec afterwards, or through a
|
|
;; slice taken of it before, does not reach the String.
|
|
(let [v (vec-new u8)]
|
|
(push v 0xc3)
|
|
(push v 0xa9)
|
|
(let [early (slice v)
|
|
t (bytes->string v)]
|
|
(set (at v 0) 0xff)
|
|
(set (at early 1) 0xe6)
|
|
(println t (length t) (rune-count t))
|
|
(free t))
|
|
(free v))
|
|
;; A remove near the front and an insert at the front, on a long text.
|
|
(let [long (string-new "é")]
|
|
(dotimes [i 1000] (append long "ab"))
|
|
(insert long 0 "x")
|
|
(println (remove long 1) (length long))
|
|
(free long))
|
|
(let [e (string-new)]
|
|
(println (length e) (rune-count e))
|
|
(free e))
|
|
(free s))
|
|
0)
|