flan/test/programs/map-keys.flan

60 lines
1.8 KiB
Plaintext

;; map-keys and map-values: the prelude's two generic walks over a map. Block
;; order is the hash's, so what comes back is sorted before it is printed.
;;
;; The three globals are named after the prelude's type variables. A generic's
;; body names its element type as $t, $k or $v, never bare, because a bare
;; name there is an expression and would find these.
(defonce t i32 0)
(defonce k i32 0)
(defonce v i32 0)
(defn adder [n i32] (Fn [i32] i32)
(fn [x] (+ x n)))
(defn main [] i32
(let [m (map-new i32 i64)]
(put m 30 (i64 300))
(put m 10 (i64 100))
(put m 20 (i64 200))
(let [ks (map-keys m)
vs (map-values m)]
(sort (slice ks))
(sort (slice vs))
(dotimes [i (length ks)] (print (at ks i)) (print " "))
(println "")
(dotimes [i (length vs)] (print (at vs i)) (print " "))
(println "")
(free ks)
(free vs))
(free m))
;; A string key, and a map that never allocated.
(let [names (map-new string i32)
none (map-new string i32)]
(put names "b" 2)
(put names "a" 1)
(let [ks (map-keys names)
nk (map-keys none)
total 0]
(dotimes [i (length ks)] (set total (+ total (or-else (get names (at ks i)) 0))))
(println total)
(println (length nk))
(free ks)
(free nk))
(free names)
(free none))
;; Closures as the values: a function value cannot be zeroed, so the walk
;; must not need a place for one.
(let [fs (map-new i32 (Fn [i32] i32))]
(put fs 1 (adder 1))
(put fs 2 (adder 2))
(let [ks (map-keys fs)
vs (map-values fs)
total 0]
(dotimes [i (length vs)] (set total (+ total ((at vs i) 10))))
(println (length ks))
(println total)
(free ks)
(free vs))
(free fs))
0)