0 | module Data.Linear.Ref1
2 | import public Data.Linear.Token
12 | data Mut : Type -> Type where [external]
14 | %extern prim__newIORef : forall a . a -> (1 x : %World) -> IORes (Mut a)
15 | %extern prim__readIORef : forall a . Mut a -> (1 x : %World) -> IORes a
16 | %extern prim__writeIORef : forall a . Mut a -> (1 val : a) -> (1 x : %World) -> IORes ()
19 | %foreign "scheme:(lambda (a x v w) (if (box-cas! x v w) 1 0))"
20 | "javascript:lambda:(a,x,v,w) => {if (x.value === v) {x.value = w; return 1;} else {return 0;}}"
21 | prim__casWrite : Mut a -> (prev,val : a) -> Bits8
29 | data Ref : (s,a : Type) -> Type where
30 | R1 : (mut : Mut a) -> Ref s a
34 | 0 IORef : Type -> Type
44 | ref1 : (v : a) -> F1 s (Ref s a)
45 | ref1 v t = let m # t := ffi (prim__newIORef v) t in R1 m # t
49 | newref : Lift1 s f => (v : a) -> f (Ref s a)
50 | newref = lift1 . ref1
55 | export %inline %deprecate
56 | newIORef : HasIO io => (v : a) -> io (IORef a)
57 | newIORef v = runIO (ref1 v)
61 | read1 : (r : Ref s a) -> F1 s a
62 | read1 (R1 m) = ffi (prim__readIORef m)
67 | readref : Lift1 s f => Ref s a -> f a
68 | readref = lift1 . read1
72 | write1 : (r : Ref s a) -> (val : a) -> F1' s
73 | write1 (R1 m) val = ffi (prim__writeIORef m val)
78 | writeref : Lift1 s f => Ref s a -> a -> f ()
79 | writeref r = lift1 . write1 r
88 | caswrite1 : (r : Ref s a) -> (pre,val : a) -> F1 s Bool
89 | caswrite1 (R1 m) pre val t =
93 | believe_me (prim__casWrite m pre val) # t
102 | casswap1 : (r : Ref s a) -> a -> F1' s
103 | casswap1 r v t = assert_total (loop t)
105 | covering loop : F1' s
107 | let cur # t := read1 r t
108 | True # t := caswrite1 r cur v t | _ # t => loop t
118 | casupdate1 : (r : Ref s a) -> (a -> (a,b)) -> F1 s b
119 | casupdate1 r f t = assert_total (loop t)
121 | covering loop : F1 s b
123 | let cur # t := read1 r t
125 | True # t := caswrite1 r cur new t | _ # t => loop t
132 | update : Lift1 s f => Ref s a -> (a -> (a,b)) -> f b
133 | update r = lift1 . casupdate1 r
142 | casmod1 : (r : Ref s a) -> (a -> a) -> F1' s
143 | casmod1 r f t = assert_total (loop t)
145 | covering loop : F1' s
147 | let cur # t := read1 r t
148 | True # t := caswrite1 r cur (f cur) t | _ # t => loop t
153 | mod1 : (r : Ref s a) -> (f : a -> a) -> F1' s
154 | mod1 r f t = let v # t2 := read1 r t in write1 r (f v) t2
160 | mod : Lift1 s f => Ref s a -> (a -> a) -> f ()
161 | mod r = lift1 . casmod1 r
166 | modAndRead1 : (r : Ref s a) -> (f : a -> a) -> F1 s a
167 | modAndRead1 r f t =
168 | let _ # t := mod1 r f t
174 | readAndMod1 : (r : Ref s a) -> (f : a -> a) -> F1 s a
175 | readAndMod1 r f t =
176 | let v # t := read1 r t
177 | _ # t := write1 r (f v) t
183 | whenRef1 : (r : Ref s Bool) -> Lazy (F1' s) -> F1' s
184 | whenRef1 r f t = let b # t1 := read1 r t in when1 b f t1
193 | 0 WithRef1 : (a,b : Type) -> Type
194 | WithRef1 a b = forall s . (r : Ref s a) -> F1 s b
198 | withRef1 : a -> WithRef1 a b -> b
199 | withRef1 v f = run1 $
\t => let r # t := ref1 v t in f r t