48 lines
1.2 KiB
Plaintext
48 lines
1.2 KiB
Plaintext
;;;; A return computes its value first and then runs the defers registered
|
|
;;;; so far, so (return x) and a last form x answer the same thing even when
|
|
;;;; a defer changes x.
|
|
(defstruct P [a i32 b i32])
|
|
|
|
(defn early [] i32
|
|
(let [x 1]
|
|
(defer (set x 2))
|
|
(return x)))
|
|
|
|
(defn fall [] i32
|
|
(let [x 1]
|
|
(defer (set x 2))
|
|
x))
|
|
|
|
(defn agg [flag bool] P
|
|
(let [p (P {.a 1 .b 1})]
|
|
(defer (set p (P {.a 9 .b 9})) (println "deferred"))
|
|
(when flag (return p))
|
|
(P {.a 5 .b 5})))
|
|
|
|
(defn unit [] ()
|
|
(defer (println "second"))
|
|
(return (println "first")))
|
|
|
|
(defn arr [] [3 i32]
|
|
(let [a [1 2 3]]
|
|
(defer (set (at a 0) 9))
|
|
(return a)))
|
|
|
|
;;;; Code after a return is never reached, and a bounds check in it is not
|
|
;;;; emitted as though it were.
|
|
(defn dead [] i32
|
|
(let [a [1 2 3]]
|
|
(return 7)
|
|
(at a 0)))
|
|
|
|
(defn main [] i32
|
|
(println (early)) ; 1
|
|
(println (fall)) ; 1
|
|
(println (.a (agg true))) ; deferred, then 1
|
|
(println (.a (agg false))) ; deferred, then 5
|
|
(unit) ; first, then second
|
|
(let [r (arr)]
|
|
(println (at r 0) (at r 1) (at r 2))) ; 1 2 3
|
|
(println (dead)) ; 7
|
|
0)
|