flan/test/programs/const-owned.flan

40 lines
1.4 KiB
Plaintext

;;;; A Vec reached through a [const (Vec T)] or a (Ptr const (Vec T)) is used
;;;; where it stands — indexed, measured, sliced, its address taken — and never
;;;; copied out as a value; (clone v) is the copy. The refusals are in
;;;; test_flan.ml; this is the half that compiles, on both backends.
(defstruct Bag [items (Vec i32) n i32])
(defn total [vs [const (Vec i32)]] i32
(let [t 0]
(dotimes [i (length vs)]
(dotimes [j (length (at vs i))]
(set t (+ t (at (at vs i) j)))))
t))
(defn first-len [p (Ptr const (Vec i32))] i32 (length (deref p)))
(defn bag-n [bs [const Bag]] i32 (+ (.n (at bs 0)) (length (.items (at bs 0)))))
(defn pick [c bool a $t b $t] $t (if c a b))
(defn main [] i32
(let [a (vec-new i32)
b (vec-new i32)]
(push a 1) (push a 2)
(push b 30)
(let [vs [a b]
cv (the-const (slice vs))
w (clone (at cv 0))
bags [(Bag {.items b .n 4})]]
(push w 99)
;; The shallow rule: the Vec's own buffer is writable through the view.
(set (at (at cv 1) 0) 31)
(println (total cv) (length w) (length (at cv 0)))
(println (first-len (addr (at cv 0))) (bag-n (slice bags)))
(println (length (pick true (bytes-view "abc") (bytes "de")))
(length (pick false (bytes "de") (bytes-view "abc"))))))
0)
(defn the-const [s [const (Vec i32)]] [const (Vec i32)] s)