56 lines
1.8 KiB
Plaintext
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)
|