flan/test/programs/update-place.flan

56 lines
1.8 KiB
Plaintext

;;;; update, ++ and -- evaluate every subexpression of their place once, as
;;;; C's compound assignment does. `calls` counts the index function: one call
;;;; per form, and the read and the write land on the same element.
(defonce calls i32 0)
(defn next-index [] i32
(set calls (+ calls 1))
(- calls 1))
(defstruct Body [velocity i32 hits [3 i32]])
(defn add [x i32 y i32] i32 (+ x y))
(defclass counter [n i32])
(defn which-slot [] dyn
(set calls (+ calls 1))
:n)
(defn main [] i32
(let [xs [10 20 30]
v (vec-new i32)
g (Body {.velocity 5})]
(push v 1) (push v 2) (push v 3)
;; next-index answers 0, then 1, then 2.
(++ (at xs (next-index)))
(-- (at v (next-index)))
(update (at xs (next-index)) * 3)
(println calls) ; 3
(println (at xs 0) (at xs 1) (at xs 2)) ; 11 20 90
(println (at v 0) (at v 1) (at v 2)) ; 1 1 3
;; A field, with a macro as the function, and with arguments after it.
(update (.velocity g) inc)
(update (.velocity g) add 10)
(println (.velocity g)) ; 16
;; A path through a field into an element: the struct is written in place,
;; not in a copy.
(set calls 0)
(update (at (.hits g) (next-index)) + 7)
(++ (at (.hits g) (next-index)))
(println calls) ; 2
(println (at (.hits g) 0) (at (.hits g) 1)) ; 7 1
;; Through a pointer.
(let [p (addr (.velocity g))]
(update (deref p) * 2)
(println (.velocity g))) ; 32
(free v))
;; A class slot, with the key computed once.
(let [c (counter 4)]
(set calls 0)
(++ (get c (which-slot)))
(update (get c (which-slot)) * 10)
(println calls (get c :n))) ; 2 50
0)