36 lines
1.4 KiB
Plaintext
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)
|