flan/test/programs/const-slice.flan

66 lines
2.3 KiB
Plaintext

;;;; [const T]: a slice that can only be read. bytes-view answers one, a [T]
;;;; converts to one wherever one is wanted, and slicing one keeps it
;;;; read-only. Nothing about it exists at run time, so this prints the same
;;;; on every backend and at every level.
(defn total [s [const i32]] i64
(let [t (i64 0)]
(dotimes [i (length s)]
(set t (+ t (at s i))))
t))
;; A generic over a read-only slice takes a writable one too.
(defn first-of [s [const $t]] $t (at s 0))
(defn widths [parts [const [const u8]]] i32
(let [n 0]
(dotimes [i (length parts)]
(set n (+ n (length (at parts i)))))
n))
;; A (Ptr const T) is what the address of read-only storage is.
(defn peek [p (Ptr const u8)] u8 (deref p))
;; A function that only reads stands where one that may write is wanted, and
;; one returning a writable slice where a read-only one is wanted.
(defn rd [s [const u8]] i32 (length s))
(defn call-rd [f (Fn [[u8]] i32)] i32 (f (bytes "abc")))
(defn call-bare [f (CFn [[u8]] i32)] i32 (f (bytes "abcd")))
(defn mk [] [u8] (bytes "xy"))
(defn call-mk [f (Fn [] [const u8])] i32 (length (f)))
(defn main [] i32
(let [xs [3 1 2]
w (slice xs)
r (bytes-view "hello, world")
head (slice r 0 5)
tail (slice r 7)
names (vec-new [const u8])]
(sort w)
(println (total w) (total (slice w 1)))
(println (first-of w) (first-of (bytes-view "z")))
(println (str head) (str tail) (length head))
(println (bytes=? head (bytes-view "hello")) (starts-with? r head))
(push names head)
(push names tail)
(println (widths (slice names)))
;; A writable [[u8]] meets [const [const u8]] too: the outer view is
;; read-only, so nothing can put a read-only slice into it.
(let [a (bytes "ab")
b (bytes "cde")
both [a b]]
(println (widths (slice both)))
(set (at a 0) \A)
(println (str a)))
(let [f (split (bytes-view "b,a,c") \,)]
(sort-bytes (slice f))
(println (join (slice f) (bytes-view "-"))))
(println (at r 0))
(println (call-rd rd) (call-bare rd) (call-mk mk))
(let [b (bytes "q")]
(println (peek (addr (at r 1))) (peek (addr (at "abc" 2)))
(peek (addr (at b 0)))
(str (slice-from (addr (at r 7)) 5))))
(free names))
0)