flan/test/programs/ptr-cast.flan

39 lines
1.2 KiB
Plaintext

;;;; ((Ptr T) p) and (slice-from p n) together: the bytes of one array read as
;;;; another element type, the way a C void * or a (Ptr u8) pixel buffer is
;;;; read as the structs it holds.
(defstruct Rgba [r u8 g u8 b u8 a u8])
(defonce bytes [8 u8])
(defn sum [s [const Rgba]] i32
(let [acc 0]
(dotimes [i (length s)]
(set acc (+ acc (i32 (.g (at s i))))))
acc))
(defn main [] ()
(dotimes [i 8]
(set (at bytes i) (u8 (+ i 1))))
;; Eight bytes are two Rgba. The count is an i64, not an i32.
(let [p ((Ptr Rgba) (addr (at bytes 0)))
n (i64 2)
px (slice-from p n)]
(println (length px)) ; 2
(println (.r (at px 0))) ; 1
(println (.a (at px 1))) ; 8
;; A write through the cast pointer is a write to the bytes.
(set (.b (at px 1)) 70)
(println (at bytes 6))) ; 70
;; Adding const is allowed, and the slice keeps it.
(let [c ((Ptr const Rgba) (addr (at bytes 0)))]
(println (sum (slice-from c (u8 2))))) ; 8
;; And back: the struct pointer read as bytes again.
(let [p ((Ptr Rgba) (addr (at bytes 0)))
b ((Ptr u8) p)]
(println (deref b)) ; 1
(println (length (slice-from b 8))))) ; 8