{-# LANGUAGE FlexibleContexts #-}

module Language.Dickinson.Pipeline ( checkEvalM
                                   , validateDecl
                                   ) where

import           Control.Monad.Except           (MonadError)
import           Control.Monad.State.Lazy       (MonadState)
import qualified Data.Text                      as T
import           Language.Dickinson.Check.Scope
import           Language.Dickinson.Error
import           Language.Dickinson.Eval
import           Language.Dickinson.Type
import           Language.Dickinson.TypeCheck

-- this one is faster with (*>) than 'do'
checkEvalM :: (MonadState (EvalSt a) m, MonadError (DickinsonError a) m) => [Declaration a] -> m T.Text
checkEvalM :: forall a (m :: * -> *).
(MonadState (EvalSt a) m, MonadError (DickinsonError a) m) =>
[Declaration a] -> m Text
checkEvalM [Declaration a]
ds =
    forall (s :: * -> *) a (m :: * -> *).
(HasTyEnv s, MonadState (s a) m,
 MonadError (DickinsonError a) m) =>
[Declaration a] -> m ()
validateDecl [Declaration a]
ds forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
    forall a (m :: * -> *).
(MonadError (DickinsonError a) m, MonadState (EvalSt a) m) =>
[Declaration a] -> m Text
evalDickinsonAsMain [Declaration a]
ds

-- the 'do'-notation is faster than using *>
validateDecl :: (HasTyEnv s, MonadState (s a) m, MonadError (DickinsonError a) m) => [Declaration a] -> m ()
validateDecl :: forall (s :: * -> *) a (m :: * -> *).
(HasTyEnv s, MonadState (s a) m,
 MonadError (DickinsonError a) m) =>
[Declaration a] -> m ()
validateDecl [Declaration a]
d = do
    forall e (m :: * -> *). MonadError e m => Maybe e -> m ()
maybeThrow forall a b. (a -> b) -> a -> b
$ forall a. [Declaration a] -> Maybe (DickinsonError a)
checkScope [Declaration a]
d
    forall (s :: * -> *) a (m :: * -> *).
(HasTyEnv s, MonadState (s a) m,
 MonadError (DickinsonError a) m) =>
[Declaration a] -> m ()
tyTraverse [Declaration a]
d