{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE Strict         #-}
module Tokstyle.C.Env where

import           Language.C.Analysis.SemRep    (Type)
import           Language.C.Analysis.TravMonad (Trav, getUserState,
                                                modifyUserState)
import           Language.C.Data.Ident         (Ident)
import           Tokstyle.C.TravUtils          (getJust)

data Env = Env
    { Env -> [String]
ctx    :: [String]
    , Env -> Maybe Type
retTy  :: Maybe Type
    , Env -> [Ident]
params :: [Ident]
    }

defaultEnv :: Env
defaultEnv :: Env
defaultEnv = [String] -> Maybe Type -> [Ident] -> Env
Env [String
"file"] Maybe Type
forall a. Maybe a
Nothing []

bracketUserState :: (s -> s) -> Trav s a -> Trav s a
bracketUserState :: (s -> s) -> Trav s a -> Trav s a
bracketUserState s -> s
f Trav s a
act = do
    s
s <- Trav s s
forall s. Trav s s
getUserState
    (s -> s) -> Trav s ()
forall s. (s -> s) -> Trav s ()
modifyUserState s -> s
f
    a
r <- Trav s a
act
    (s -> s) -> Trav s ()
forall s. (s -> s) -> Trav s ()
modifyUserState (s -> s -> s
forall a b. a -> b -> a
const s
s)
    a -> Trav s a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r


getCtx :: Trav Env [String]
getCtx :: Trav Env [String]
getCtx = Env -> [String]
ctx (Env -> [String]) -> TravT Env Identity Env -> Trav Env [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TravT Env Identity Env
forall s. Trav s s
getUserState

pushCtx :: String -> Trav Env ()
pushCtx :: String -> Trav Env ()
pushCtx String
s = (Env -> Env) -> Trav Env ()
forall s. (s -> s) -> Trav s ()
modifyUserState ((Env -> Env) -> Trav Env ()) -> (Env -> Env) -> Trav Env ()
forall a b. (a -> b) -> a -> b
$ \env :: Env
env@Env{[String]
ctx :: [String]
ctx :: Env -> [String]
ctx} -> Env
env{ctx :: [String]
ctx = String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ctx}

popCtx :: Trav Env ()
popCtx :: Trav Env ()
popCtx = (Env -> Env) -> Trav Env ()
forall s. (s -> s) -> Trav s ()
modifyUserState ((Env -> Env) -> Trav Env ()) -> (Env -> Env) -> Trav Env ()
forall a b. (a -> b) -> a -> b
$ \env :: Env
env@Env{[String]
ctx :: [String]
ctx :: Env -> [String]
ctx} -> Env
env{ctx :: [String]
ctx = [String] -> [String]
forall a. [a] -> [a]
tail [String]
ctx}


getRetTy :: Trav Env Type
getRetTy :: Trav Env Type
getRetTy = TravT Env Identity Env
forall s. Trav s s
getUserState TravT Env Identity Env -> (Env -> Trav Env Type) -> Trav Env Type
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Maybe Type -> Trav Env Type
forall (m :: * -> *) a. MonadTrav m => String -> Maybe a -> m a
getJust String
"not in function context" (Maybe Type -> Trav Env Type)
-> (Env -> Maybe Type) -> Env -> Trav Env Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Env -> Maybe Type
retTy

setRetTy :: Type -> Trav Env ()
setRetTy :: Type -> Trav Env ()
setRetTy Type
t = (Env -> Env) -> Trav Env ()
forall s. (s -> s) -> Trav s ()
modifyUserState ((Env -> Env) -> Trav Env ()) -> (Env -> Env) -> Trav Env ()
forall a b. (a -> b) -> a -> b
$ \Env
env -> Env
env{retTy :: Maybe Type
retTy = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
t}

unsetRetTy :: Trav Env ()
unsetRetTy :: Trav Env ()
unsetRetTy = (Env -> Env) -> Trav Env ()
forall s. (s -> s) -> Trav s ()
modifyUserState ((Env -> Env) -> Trav Env ()) -> (Env -> Env) -> Trav Env ()
forall a b. (a -> b) -> a -> b
$ \Env
env -> Env
env{retTy :: Maybe Type
retTy = Maybe Type
forall a. Maybe a
Nothing}