module Parsley.Register (
Reg, newRegister, get, put,
newRegister_,
put_,
gets, gets_,
modify, modify_,
move, swap,
local, local_,
localModify, localModify_,
bind, rollback,
for
) where
import Prelude hiding (pure, (<*>), (*>), (<*))
import Parsley.Alternative (empty, (<|>))
import Parsley.Applicative (pure, (<*>), (*>), (<*))
import Parsley.Internal (Parser, Reg)
import Parsley.ParserOps (ParserOps)
import Parsley.Selective (when, while)
import qualified Parsley.Internal as Internal (newRegister, get, put)
newRegister :: Parser a
-> (forall r. Reg r a -> Parser b)
-> Parser b
newRegister :: Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister = Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
forall a b. Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
Internal.newRegister
get :: Reg r a -> Parser a
get :: Reg r a -> Parser a
get = Reg r a -> Parser a
forall r a. Reg r a -> Parser a
Internal.get
put :: Reg r a -> Parser a -> Parser ()
put :: Reg r a -> Parser a -> Parser ()
put = Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
Internal.put
newRegister_ :: ParserOps rep => rep a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister_ :: rep a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister_ rep a
x = Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
forall a b. Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister (rep a -> Parser a
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure rep a
x)
put_ :: ParserOps rep => Reg r a -> rep a -> Parser ()
put_ :: Reg r a -> rep a -> Parser ()
put_ Reg r a
r = Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r (Parser a -> Parser ())
-> (rep a -> Parser a) -> rep a -> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rep a -> Parser a
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure
gets :: Reg r a -> Parser (a -> b) -> Parser b
gets :: Reg r a -> Parser (a -> b) -> Parser b
gets Reg r a
r Parser (a -> b)
p = Parser (a -> b)
p Parser (a -> b) -> Parser a -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r a
r
gets_ :: ParserOps rep => Reg r a -> rep (a -> b) -> Parser b
gets_ :: Reg r a -> rep (a -> b) -> Parser b
gets_ Reg r a
r = Reg r a -> Parser (a -> b) -> Parser b
forall r a b. Reg r a -> Parser (a -> b) -> Parser b
gets Reg r a
r (Parser (a -> b) -> Parser b)
-> (rep (a -> b) -> Parser (a -> b)) -> rep (a -> b) -> Parser b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rep (a -> b) -> Parser (a -> b)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure
modify :: Reg r a -> Parser (a -> a) -> Parser ()
modify :: Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r a
r Parser (a -> a)
p = Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r (Reg r a -> Parser (a -> a) -> Parser a
forall r a b. Reg r a -> Parser (a -> b) -> Parser b
gets Reg r a
r Parser (a -> a)
p)
modify_ :: ParserOps rep => Reg r a -> rep (a -> a) -> Parser ()
modify_ :: Reg r a -> rep (a -> a) -> Parser ()
modify_ Reg r a
r = Reg r a -> Parser (a -> a) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r a
r (Parser (a -> a) -> Parser ())
-> (rep (a -> a) -> Parser (a -> a)) -> rep (a -> a) -> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rep (a -> a) -> Parser (a -> a)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure
move :: Reg r1 a -> Reg r2 a -> Parser ()
move :: Reg r1 a -> Reg r2 a -> Parser ()
move Reg r1 a
dst Reg r2 a
src = Reg r1 a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r1 a
dst (Reg r2 a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r2 a
src)
bind :: Parser a -> (Parser a -> Parser b) -> Parser b
bind :: Parser a -> (Parser a -> Parser b) -> Parser b
bind Parser a
p Parser a -> Parser b
f = Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
forall a b. Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister Parser a
p (Parser a -> Parser b
f (Parser a -> Parser b)
-> (Reg r a -> Parser a) -> Reg r a -> Parser b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get)
local :: Reg r a -> Parser a -> Parser b -> Parser b
local :: Reg r a -> Parser a -> Parser b -> Parser b
local Reg r a
r Parser a
p Parser b
q = Parser a -> (Parser a -> Parser b) -> Parser b
forall a b. Parser a -> (Parser a -> Parser b) -> Parser b
bind (Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r a
r) ((Parser a -> Parser b) -> Parser b)
-> (Parser a -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Parser a
x -> Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r Parser a
p
Parser () -> Parser b -> Parser b
forall a b. Parser a -> Parser b -> Parser b
*> Parser b
q
Parser b -> Parser () -> Parser b
forall a b. Parser a -> Parser b -> Parser a
<* Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r Parser a
x
local_ :: ParserOps rep => Reg r a -> rep a -> Parser b -> Parser b
local_ :: Reg r a -> rep a -> Parser b -> Parser b
local_ Reg r a
r = Reg r a -> Parser a -> Parser b -> Parser b
forall r a b. Reg r a -> Parser a -> Parser b -> Parser b
local Reg r a
r (Parser a -> Parser b -> Parser b)
-> (rep a -> Parser a) -> rep a -> Parser b -> Parser b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rep a -> Parser a
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure
localModify :: Reg r a -> Parser (a -> a) -> Parser b -> Parser b
localModify :: Reg r a -> Parser (a -> a) -> Parser b -> Parser b
localModify Reg r a
r Parser (a -> a)
p Parser b
q = Parser a -> (Parser a -> Parser b) -> Parser b
forall a b. Parser a -> (Parser a -> Parser b) -> Parser b
bind (Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r a
r) ((Parser a -> Parser b) -> Parser b)
-> (Parser a -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Parser a
x -> Reg r a -> Parser (a -> a) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r a
r Parser (a -> a)
p
Parser () -> Parser b -> Parser b
forall a b. Parser a -> Parser b -> Parser b
*> Parser b
q
Parser b -> Parser () -> Parser b
forall a b. Parser a -> Parser b -> Parser a
<* Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r Parser a
x
localModify_ :: ParserOps rep => Reg r a -> rep (a -> a) -> Parser b -> Parser b
localModify_ :: Reg r a -> rep (a -> a) -> Parser b -> Parser b
localModify_ Reg r a
r = Reg r a -> Parser (a -> a) -> Parser b -> Parser b
forall r a b. Reg r a -> Parser (a -> a) -> Parser b -> Parser b
localModify Reg r a
r (Parser (a -> a) -> Parser b -> Parser b)
-> (rep (a -> a) -> Parser (a -> a))
-> rep (a -> a)
-> Parser b
-> Parser b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. rep (a -> a) -> Parser (a -> a)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure
swap :: Reg r1 a -> Reg r2 a -> Parser ()
swap :: Reg r1 a -> Reg r2 a -> Parser ()
swap Reg r1 a
r1 Reg r2 a
r2 = Parser a -> (Parser a -> Parser ()) -> Parser ()
forall a b. Parser a -> (Parser a -> Parser b) -> Parser b
bind (Reg r1 a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r1 a
r1) ((Parser a -> Parser ()) -> Parser ())
-> (Parser a -> Parser ()) -> Parser ()
forall a b. (a -> b) -> a -> b
$ \Parser a
x -> Reg r1 a -> Reg r2 a -> Parser ()
forall r1 a r2. Reg r1 a -> Reg r2 a -> Parser ()
move Reg r1 a
r1 Reg r2 a
r2
Parser () -> Parser () -> Parser ()
forall a b. Parser a -> Parser b -> Parser b
*> Reg r2 a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r2 a
r2 Parser a
x
rollback :: Reg r a -> Parser b -> Parser b
rollback :: Reg r a -> Parser b -> Parser b
rollback Reg r a
r Parser b
p = Parser a -> (Parser a -> Parser b) -> Parser b
forall a b. Parser a -> (Parser a -> Parser b) -> Parser b
bind (Reg r a -> Parser a
forall r a. Reg r a -> Parser a
get Reg r a
r) ((Parser a -> Parser b) -> Parser b)
-> (Parser a -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Parser a
x -> Parser b
p Parser b -> Parser b -> Parser b
forall a. Parser a -> Parser a -> Parser a
<|> Reg r a -> Parser a -> Parser ()
forall r a. Reg r a -> Parser a -> Parser ()
put Reg r a
r Parser a
x Parser () -> Parser b -> Parser b
forall a b. Parser a -> Parser b -> Parser b
*> Parser b
forall a. Parser a
empty
for :: Parser a -> Parser (a -> Bool) -> Parser (a -> a) -> Parser () -> Parser ()
for :: Parser a
-> Parser (a -> Bool) -> Parser (a -> a) -> Parser () -> Parser ()
for Parser a
init Parser (a -> Bool)
cond Parser (a -> a)
step Parser ()
body =
Parser a -> (forall r. Reg r a -> Parser ()) -> Parser ()
forall a b. Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister Parser a
init ((forall r. Reg r a -> Parser ()) -> Parser ())
-> (forall r. Reg r a -> Parser ()) -> Parser ()
forall a b. (a -> b) -> a -> b
$ \Reg r a
i ->
let cond' :: Parser Bool
cond' :: Parser Bool
cond' = Reg r a -> Parser (a -> Bool) -> Parser Bool
forall r a b. Reg r a -> Parser (a -> b) -> Parser b
gets Reg r a
i Parser (a -> Bool)
cond
in Parser Bool -> Parser () -> Parser ()
when Parser Bool
cond' (Parser Bool -> Parser ()
while (Parser ()
body Parser () -> Parser () -> Parser ()
forall a b. Parser a -> Parser b -> Parser b
*> Reg r a -> Parser (a -> a) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r a
i Parser (a -> a)
step Parser () -> Parser Bool -> Parser Bool
forall a b. Parser a -> Parser b -> Parser b
*> Parser Bool
cond'))