2 | import Control.Monad.Resource
5 | import Data.C.Integer
7 | import Data.Linear.ELift1
10 | import public Data.Fin
11 | import public Data.Linear.Token
12 | import public Data.Array.Index
13 | import public Data.C.Struct
23 | export %foreign "C__collect_safe:cptr_copy, cptr-idris"
24 | prim__copy_pp : AnyPtr -> AnyPtr -> Bits32 -> PrimIO ()
26 | export %foreign "C:cptr_copy, cptr-idris"
27 | prim__copy_pb : AnyPtr -> Buffer -> Bits32 -> PrimIO ()
29 | export %foreign "C:cptr_copy, cptr-idris"
30 | prim__copy_bp : Buffer -> AnyPtr -> Bits32 -> PrimIO ()
32 | export %foreign "C:cptr_inc_ptr, cptr-idris"
33 | "scheme,chez:(lambda (p x y) (+ p (* x y)))"
34 | prim__inc_ptr : AnyPtr -> Bits32 -> Bits32 -> AnyPtr
36 | export %foreign "C:cptr_scrub, cptr-idris"
37 | prim__scrub : AnyPtr -> Bits32 -> PrimIO ()
57 | record CIArray (n : Nat) (a : Type) where
61 | parameters {0 a : Type}
63 | {auto so : SizeOf a}
67 | at : CIArray n a -> Fin n -> a
69 | let MkIORes v _ := toPrim (deref $
prim__inc_ptr r.ptr (sizeof a) (cast $
finToNat x)) %MkWorld
73 | ix : CIArray n a -> (0 m : Nat) -> (x : Ix (S m) n) => a
74 | ix r m = at r (ixToFin x)
77 | atNat : CIArray n a -> (m : Nat) -> (0 lt : LT m n) => a
78 | atNat r m = at r (natToFinLT m)
80 | foldrI : (m : Nat) -> (0 _ : LTE m n) => (a -> b -> b) -> b -> CIArray n a -> b
82 | foldrI (S k) f x r = foldrI k f (f (atNat r k) x) r
86 | -> {auto 0 prf : LTE m n}
87 | -> (Fin n -> a -> b -> b)
91 | foldrKV_ 0 _ x r = x
92 | foldrKV_ (S k) f x r =
93 | let fin := natToFinLT k @{prf} in foldrKV_ k f (f fin (at r fin) x) r
95 | foldlI : (m : Nat) -> (x : Ix m n) => (b -> a -> b) -> b -> CIArray n a -> b
97 | foldlI (S k) f v r = foldlI k f (f v (ix r k)) r
101 | -> {auto x : Ix m n}
102 | -> (Fin n -> b -> a -> b)
106 | foldlKV_ 0 _ v r = v
107 | foldlKV_ (S k) f v r =
108 | let fin := ixToFin x in foldlKV_ k f (f fin v (at r fin)) r
114 | -> {auto 0 lt : LTE k n}
116 | ontoVect r vs 0 = rewrite plusCommutative m 0 in vs
117 | ontoVect r vs (S x) =
118 | let v := atNat r x {lt}
119 | in rewrite sym (plusSuccRightSucc m x) in ontoVect r (v::vs) x
121 | parameters {n : Nat}
122 | {auto sz : SizeOf a}
123 | {auto de : Deref a}
127 | toVect : (r : CIArray n a) -> Vect n a
128 | toVect r = ontoVect r [] n
132 | foldrKV : (Fin n -> a -> b -> b) -> b -> CIArray n a -> b
133 | foldrKV = foldrKV_ n
137 | foldr : (a -> b -> b) -> b -> CIArray n a -> b
142 | foldlKV : (Fin n -> b -> a -> b) -> b -> CIArray n a -> b
143 | foldlKV = foldlKV_ n
147 | foldl : (b -> a -> b) -> b -> CIArray n a -> b
157 | withPtr : HasIO io => Bits32 -> (AnyPtr -> io a) -> io a
158 | withPtr sz f = Prelude.do
159 | ptr <- pure $
prim__malloc sz
161 | primIO $
prim__free ptr
178 | record PrimCArray (s : Type) (b : Bool) (n : Nat) (a : Type) where
184 | 0 CArray : (s : Type) -> (n : Nat) -> (a : Type) -> Type
185 | CArray s n a = PrimCArray s False n a
189 | 0 CArrayS : (s : Type) -> (n : Nat) -> (a : Type) -> Type
190 | CArrayS s n a = PrimCArray s True n a
194 | 0 CArrayIO : (n : Nat) -> (a : Type) -> Type
195 | CArrayIO n a = PrimCArray World False n a
199 | 0 CArrayIOS : (n : Nat) -> (a : Type) -> Type
200 | CArrayIOS n a = PrimCArray World True n a
202 | public export %inline
203 | {n : Nat} -> SizeOf a => SizeOf (CArray s n a) where
204 | sizeof_ = cast n * sizeof a
207 | unsafeUnwrap : CArray s n a -> AnyPtr
211 | unsafeWrap : AnyPtr -> CArray s n a
215 | 0 IOBox : Type -> Type
219 | 0 Box : Type -> Type -> Type
230 | -> {auto so : SizeOf a}
232 | -> F1 s (CArray s n a)
234 | let p := prim__malloc (cast n * sizeof a)
241 | -> {auto so : SizeOf a}
243 | -> F1 s (CArray s n a)
245 | let p := prim__calloc (cast n) (sizeof a)
251 | free1 : (r : CArray s n a) -> F1' s
252 | free1 r = ffi (prim__free r.ptr)
257 | frees1 : {0 a : Type} -> {auto so : SizeOf a} -> {n : Nat} -> (r : CArrayS s n a) -> F1' s
259 | let () # t := ffi (prim__scrub r.ptr (cast n * sizeof a)) t
260 | in ffi (prim__free r.ptr) t
264 | unbox : Deref a => (r : CArray s (S n) a) -> F1 s a
265 | unbox r = ffi $
toPrim (deref r.ptr)
267 | parameters {0 f : Type -> Type}
270 | {auto sr : Struct f}
271 | {auto so : SizeOf (f s)}
272 | (r : CArray s n (f s))
276 | getStruct : Fin n -> F1 s (f s)
278 | let ptr := prim__inc_ptr r.ptr (cast $
finToNat x) (sizeof $
f s)
283 | getStructIx : (0 m : Nat) -> (x : Ix (S m) n) => F1 s (f s)
284 | getStructIx m = getStruct (ixToFin x)
288 | getStructNat : (m : Nat) -> (0 lt : LT m n) => F1 s (f s)
289 | getStructNat m = getStruct (natToFinLT m)
291 | parameters {0 a : Type}
293 | {auto so : SizeOf a}
298 | get : Deref a => Fin n -> F1 s a
299 | get x = ffi $
toPrim (deref $
prim__inc_ptr r.ptr (cast $
finToNat x) (sizeof a))
303 | getIx : Deref a => (0 m : Nat) -> (x : Ix (S m) n) => F1 s a
304 | getIx m = get (ixToFin x)
308 | getNat : Deref a => (m : Nat) -> (0 lt : LT m n) => F1 s a
309 | getNat m = get (natToFinLT m)
313 | set : SetPtr a => Fin n -> a -> F1' s
314 | set x v = ffi $
toPrim (setPtr (prim__inc_ptr r.ptr (cast $
finToNat x) (sizeof a)) v)
318 | setIx : SetPtr a => (0 m : Nat) -> (x : Ix (S m) n) => a -> F1' s
319 | setIx m = set (ixToFin x)
323 | setNat : SetPtr a => (m : Nat) -> (0 lt : LT m n) => a -> F1' s
324 | setNat m = set (natToFinLT m)
326 | writeVect1 : SetPtr a => Vect k a -> Ix k n => F1' s
327 | writeVect1 [] t = () # t
328 | writeVect1 {k = S m} (x :: xs) t =
329 | let _ # t := setIx m x t
334 | writeVect : SetPtr a => Vect n a -> F1' s
335 | writeVect as = writeVect1 as
344 | withIArray : (CIArray n a -> b) -> F1 s b
345 | withIArray f t = f (IA r.ptr) # t
350 | {auto so : SizeOf a}
351 | -> {auto sp : SetPtr a}
353 | -> (r : CArray s (length as) a)
355 | writeList as r = writeVect r (fromList as)
358 | withCArray : SizeOf a => (n : Nat) -> (f : forall s . CArray s n a -> F1 s b) -> b
361 | let r # t := malloc1 a n t
370 | parameters {auto has : Lift1 s f}
374 | malloc : (0 a : Type) -> SizeOf a => (n : Nat) -> f (CArray s n a)
375 | malloc a n = lift1 (malloc1 a n)
379 | calloc : (0 a : Type) -> SizeOf a => (n : Nat) -> f (CArray s n a)
380 | calloc a n = lift1 (calloc1 a n)
393 | free : CArray s n a -> f ()
394 | free arr = lift1 (free1 arr)
397 | fromList : SizeOf a => SetPtr a => (as : List a) -> f (CArray s (length as) a)
398 | fromList as = Prelude.do
399 | arr <- malloc a (length as)
400 | lift1 $
writeList as arr
408 | ELift1 s f => Resource f (CArray s n a) where
409 | cleanup arr = lift1 (free1 arr)