2 | module Data.Array.Core
4 | import Data.Array.Index
7 | import Data.Linear.Token
11 | import Data.Buffer.Core as BC
26 | %foreign "scheme:(lambda (x) (make-vector x))"
27 | "javascript:lambda:(n,w) => new Array(Number(n))"
28 | prim__emptyArray : Integer -> PrimIO AnyPtr
31 | %foreign "scheme:(lambda (x i) (make-vector x i))"
32 | "javascript:lambda:(bi,x,w) => Array(Number(bi)).fill(x)"
33 | prim__newArray : Integer -> AnyPtr -> PrimIO AnyPtr
36 | %foreign "scheme:(lambda (x i) (vector-ref x i))"
37 | "javascript:lambda:(x,bi) => x[Number(bi)]"
38 | prim__arrayGet : AnyPtr -> Integer -> AnyPtr
43 | %foreign "scheme:(lambda (b a o) (vector-ref b (+ a o)))"
44 | "scheme,chez:(lambda (b a o) (vector-ref b (fx+ a o)))"
45 | "javascript:lambda:(buf,at,offset)=>buf[Number(offset) + Number(at)]"
46 | prim__arrayGetOffset : AnyPtr -> (at, offset : Integer) -> AnyPtr
49 | %foreign "scheme:(lambda (x i w) (vector-set! x i w))"
50 | "javascript:lambda:(x,bi,w) => {const i = Number(bi); x[i] = w}"
51 | prim__arraySet : AnyPtr -> Integer -> (val : AnyPtr) -> PrimIO ()
54 | %foreign "scheme:(lambda (a x i v w) (if (vector-cas! x i v w) 1 0))"
55 | "javascript:lambda:(a,x,bi,v,w) => {const i = Number(bi); if (x[i] === v) {x[i] = w; return 1;} else {return 0;}}"
56 | prim__casSet : AnyPtr -> Integer -> (prev,val : a) -> Bits8
59 | %foreign "scheme: (lambda (b1 o1 len b2 o2) (letrec ((go (lambda (i) (when (< i len) (begin (vector-set! b2 (+ o2 i) (vector-ref b1 (+ o1 i))) (go (+ 1 i))))))) (go 0)))"
60 | "scheme,chez: (lambda (b1 o1 len b2 o2) (letrec ((go (lambda (i) (when (< i len) (begin (vector-set! b2 (fx+ o2 i) (vector-ref b1 (fx+ o1 i))) (go (fx+ 1 i))))))) (go 0)))"
61 | "javascript:lambda:(b1,bo1,blen,b2,bo2,t)=> {const o1 = Number(bo1); const len = Number(blen); const o2 = Number(bo2); for (let i = 0; i < len; i++) {b2[o2+i] = b1[o1+i];}; return t}"
62 | prim__copyArray : (src : AnyPtr) -> (srcOffset, len : Integer) ->
63 | (dst : AnyPtr) -> (dstOffset : Integer) -> PrimIO ()
66 | %foreign "scheme: (lambda (b1 o1 len b2 o2) (letrec ((go (lambda (i) (when (< i len) (begin (vector-set! b2 (+ o2 i) (bytevector-u8-ref b1 (+ o1 i))) (go (+ 1 i))))))) (go 0)))"
67 | "scheme,chez: (lambda (b1 o1 len b2 o2) (letrec ((go (lambda (i) (when (< i len) (begin (vector-set! b2 (fx+ o2 i) (bytevector-u8-ref b1 (fx+ o1 i))) (go (fx+ 1 i))))))) (go 0)))"
68 | "javascript:lambda:(b1,bo1,blen,b2,bo2,t)=> {const o1 = Number(bo1); const len = Number(blen); const o2 = Number(bo2); for (let i = 0; i < len; i++) {b2[o2+i] = b1[o1+i];}; return t}"
69 | prim__bufToArr : (src : Buffer) -> (srcOffset, len : Integer) ->
70 | (dst : AnyPtr) -> (dstOffset : Integer) -> PrimIO ()
73 | %foreign "scheme: (lambda (b1 o1 len b2 o2) (letrec ((go (lambda (i) (when (< i len) (begin (bytevector-u8-set! b2 (+ o2 i) (vector-ref b1 (+ o1 i))) (go (+ 1 i))))))) (go 0)))"
74 | "scheme,chez: (lambda (b1 o1 len b2 o2) (letrec ((go (lambda (i) (when (< i len) (begin (bytevector-u8-set! b2 (fx+ o2 i) (vector-ref b1 (fx+ o1 i))) (go (fx+ 1 i))))))) (go 0)))"
75 | "javascript:lambda:(b1,bo1,blen,b2,bo2,t)=> {const o1 = Number(bo1); const len = Number(blen); const o2 = Number(bo2); for (let i = 0; i < len; i++) {b2[o2+i] = b1[o1+i];}; return t}"
76 | prim__arrToBuf : (src : AnyPtr) -> (srcOffset, len : Integer) ->
77 | (dst : Buffer) -> (dstOffset : Integer) -> PrimIO ()
80 | %foreign "javascript:lambda:(x,t)=> x.length"
81 | prim__jsArrLength : AnyPtr -> PrimIO Bits32
89 | record IArray (n : Nat) (a : Type) where
95 | at : IArray n a -> Fin n -> a
96 | at (IA ad) m = believe_me $
prim__arrayGet ad (cast $
finToNat m)
100 | atByte : IArray 256 a -> Bits8 -> a
101 | atByte (IA ad) m = believe_me $
prim__arrayGet ad (cast m)
106 | atOffset : IArray n a -> Fin m -> (off : Nat) -> (0 p : LTE (off+m) n) => a
107 | atOffset (IA ad) m off =
108 | believe_me $
prim__arrayGetOffset ad (cast $
finToNat m) (cast off)
117 | take : (0 m : Nat) -> IArray n a -> {auto 0 lte : LTE m n} -> IArray m a
118 | take _ (IA arr) = IA arr
126 | unsafeToPtr : IArray n a -> AnyPtr
127 | unsafeToPtr (IA p) = p
135 | data MArray : (s : Type) -> (n : Nat) -> (a : Type) -> Type where
136 | MA : (arr : AnyPtr) -> MArray s n a
140 | 0 IOArray : Nat -> Type -> Type
141 | IOArray = MArray World
149 | unsafeMToPtr : MArray s n a -> AnyPtr
150 | unsafeMToPtr (MA p) = p
158 | marray1 : (n : Nat) -> a -> F1 s (MArray s n a)
160 | let p # t := ffi (prim__newArray (cast n) (believe_me v)) t in MA p # t
164 | marray : Lift1 s f => (n : Nat) -> a -> f (MArray s n a)
165 | marray n v = lift1 (marray1 n v)
168 | unsafeMArray1 : (n : Nat) -> F1 s (MArray s n a)
169 | unsafeMArray1 n t =
170 | let p # t := ffi (prim__emptyArray (cast n)) t in MA p # t
174 | unsafeMArray : Lift1 s f => (n : Nat) -> f (MArray s n a)
175 | unsafeMArray n = lift1 (unsafeMArray1 n)
179 | set : (r : MArray s n a) -> Fin n -> a -> F1' s
180 | set (MA arr) ix v = ffi (prim__arraySet arr (cast $
finToNat ix) (believe_me v))
184 | setBits8 : (r : MArray s 256 a) -> Bits8 -> a -> F1' s
185 | setBits8 (MA arr) ix v = ffi (prim__arraySet arr (cast ix) (believe_me v))
193 | get : (r : MArray s n a) -> Fin n -> F1 s a
194 | get (MA arr) ix t = believe_me (prim__arrayGet arr (cast $
finToNat ix)) # t
202 | getBits8 : (r : MArray s 256 a) -> Bits8 -> F1 s a
203 | getBits8 (MA arr) ix t = believe_me (prim__arrayGet arr (cast ix)) # t
207 | modify : (r : MArray s n a) -> Fin n -> (a -> a) -> F1' s
208 | modify r ix f t = let v # t1 := get r ix t in set r ix (f v) t1
217 | casset : (r : MArray s n a) -> Fin n -> (pre,val : a) -> F1 s Bool
218 | casset (MA arr) x pre val t =
219 | case prim__casSet arr (cast $
finToNat x) pre val of
229 | casswap : (r : MArray s n a) -> Fin n -> a -> F1' s
230 | casswap r x v t = assert_total (loop t)
232 | covering loop : F1' s
234 | let cur # t := get r x t
235 | True # t := casset r x cur v t | _ # t => loop t
244 | casupdate : (r : MArray s n a) -> Fin n -> (a -> (a,b)) -> F1 s b
245 | casupdate r x f t = assert_total (loop t)
247 | covering loop : F1 s b
249 | let cur # t := get r x t
251 | True # t := casset r x cur new t | _ # t => loop t
261 | casmodify : (r : MArray s n a) -> Fin n -> (a -> a) -> F1' s
262 | casmodify r x f t = assert_total (loop t)
264 | covering loop : F1' s
266 | let cur # t := get r x t
267 | True # t := casset r x cur (f cur) t | _ # t => loop t
272 | mtake : MArray s n a -> (0 m : Nat) -> (0 lte : LTE m n) => F1 s (MArray s m a)
273 | mtake (MA arr) _ t = MA arr # t
278 | -> (srcOffset,dstOffset : Nat)
280 | -> {auto 0 p1 : LTE (srcOffset + len) m}
281 | -> {auto 0 p2 : LTE (dstOffset + len) n}
282 | -> (r : MArray s n a)
284 | copy (MA src) srcOffset dstOffset len (MA dst) =
285 | ffi (prim__copyArray src (cast srcOffset) (cast len) dst (cast dstOffset))
290 | -> (srcOffset,dstOffset : Nat)
292 | -> {auto 0 p1 : LTE (srcOffset + len) m}
293 | -> {auto 0 p2 : LTE (dstOffset + len) n}
294 | -> (r : MArray s n a)
296 | icopy (IA src) = copy {m} (MA src)
301 | -> (srcOffset,dstOffset : Nat)
303 | -> {auto 0 p1 : LTE (srcOffset + len) m}
304 | -> {auto 0 p2 : LTE (dstOffset + len) n}
305 | -> (r : MBuffer s n)
307 | copyToBuf (MA src) srcOffset dstOffset len dst =
308 | ffi (prim__arrToBuf src (cast srcOffset) (cast len) (unsafeFromMBuffer dst) (cast dstOffset))
313 | -> (srcOffset,dstOffset : Nat)
315 | -> {auto 0 p1 : LTE (srcOffset + len) m}
316 | -> {auto 0 p2 : LTE (dstOffset + len) n}
317 | -> (r : MBuffer s n)
319 | icopyToBuf (IA src) = copyToBuf {m} (MA src)
324 | -> (srcOffset,dstOffset : Nat)
326 | -> {auto 0 p1 : LTE (srcOffset + len) m}
327 | -> {auto 0 p2 : LTE (dstOffset + len) n}
328 | -> (r : MArray s n Bits8)
330 | copyToArray src srcOffset dstOffset len (MA dst) =
331 | ffi (prim__bufToArr (unsafeFromMBuffer src) (cast srcOffset) (cast len) dst (cast dstOffset))
336 | -> (srcOffset,dstOffset : Nat)
338 | -> {auto 0 p1 : LTE (srcOffset + len) m}
339 | -> {auto 0 p2 : LTE (dstOffset + len) n}
340 | -> (r : MArray s n Bits8)
342 | icopyToArray buf = copyToArray {m} (unsafeMBuffer $
unsafeGetBuffer buf)
346 | thaw : {n : _} -> IArray n a -> F1 s (MArray s n a)
348 | let r # t := unsafeMArray1 n t
349 | _ # t := icopy src 0 0 n @{reflexive} @{reflexive} r t
357 | unsafeThaw : IArray n a -> MArray s n a
358 | unsafeThaw (IA arr) = MA arr
365 | 0 WithMArray : Nat -> (a,b : Type) -> Type
366 | WithMArray n a b = forall s . (r : MArray s n a) -> F1 s b
370 | alloc : (n : Nat) -> a -> (fun : WithMArray n a b) -> b
371 | alloc n v f = run1 $
\t => let r # t2 := marray1 n v t in f r t2
383 | unsafeAlloc : (n : Nat) -> (fun : WithMArray n a b) -> b
384 | unsafeAlloc n f = run1 $
\t => let r # t2 := unsafeMArray1 n t in f r t2
403 | {auto 0 _ : LTE m n}
404 | -> (r : MArray s n a)
406 | -> F1 s (IArray m a)
407 | unsafeFreezeLTE (MA arr) _ t = IA arr # t
415 | unsafeFreeze : (r : MArray s n a) -> F1 s (IArray n a)
416 | unsafeFreeze r = unsafeFreezeLTE @{reflexive} r n
420 | freezeLTE : MArray s n a -> (m : Nat) -> (0 p : LTE m n) => F1 s (IArray m a)
421 | freezeLTE src m t =
422 | let r@(MA buf) # t := unsafeMArray1 m t
423 | _ # t := copy src 0 0 m @{p} @{reflexive} r t
428 | freeze : {n : _} -> MArray s n a -> F1 s (IArray n a)
429 | freeze src = freezeLTE src n @{reflexive}
437 | toIBuffer : {n : _} -> IArray n Bits8 -> IBuffer n
439 | alloc n $
\buf,t =>
440 | let _ # t := icopyToBuf arr 0 0 n buf t
441 | in unsafeFreeze buf t
445 | toIArray : {n : _} -> IBuffer n -> IArray n Bits8
447 | alloc n (the Bits8 0) $
\arr,t =>
448 | let _ # t := icopyToArray buf 0 0 n arr t
449 | in unsafeFreeze arr t
462 | unsafeJSMArrayOf1 : (0 a : Type) -> AnyPtr -> F1 s (
n ** MArray s n a)
463 | unsafeJSMArrayOf1 a ptr t =
464 | let len # t := ffi (prim__jsArrLength ptr) t
465 | in (
cast len ** MA ptr)
# t
469 | unsafeJSMArrayOf : HasIO io => (0 a : Type) -> AnyPtr -> io (
n ** IOArray n a)
470 | unsafeJSMArrayOf a ptr = runIO (unsafeJSMArrayOf1 a ptr)