flan/test/programs/grow-param.flan

36 lines
1.4 KiB
Plaintext

;;;; A container parameter is a copy of the caller's header. Growing it grows
;;;; the copy, so the caller's container does not see the push; the function
;;;; is warned at, at the parameter, and the fix it names is the (Ptr ...)
;;;; below, which reaches the caller's own header. A struct passed by value
;;;; is a copy too, with its Vec fields in it, and is warned at the same way.
(defstruct Bag [items (Vec i32) n i32])
(defstruct Box [bag Bag])
(defn add-copy [v (Vec i32)] () (push v 1) (free v))
(defn add-ptr [v (Ptr (Vec i32))] () (push (deref v) 2))
(defn put-ptr [m (Ptr (Map i32 i32))] () (put (deref m) 7 8))
(defn bag-copy [b Bag] () (push (.items b) 1) (free (.items b)))
(defn bag-ptr [x (Ptr Box)] () (push (.items (.bag x)) 3))
(defn main [] i32
(let [v (vec-new i32)
m (map-new i32 i32)]
(add-copy v)
(println (length v)) ; 0
(add-ptr (addr v))
(add-ptr (addr v))
(println (length v)) ; 2
(println (at v 1)) ; 2
(put-ptr (addr m))
(println (length m)) ; 1
(free v)
(free m))
(let [x (Box {.bag (Bag {.items (vec-new i32) .n 0})})]
(bag-copy (.bag x))
(println (length (.items (.bag x)))) ; 0
(bag-ptr (addr x))
(println (at (.items (.bag x)) 0)) ; 3
(free (.items (.bag x))))
0)