language-dickinson-0.1.0.0: src/Language/Dickinson/Lib/Get.hs
{-# LANGUAGE FlexibleContexts #-}
module Language.Dickinson.Lib.Get ( parseImportM
, parseFpM
) where
import Control.Composition ((.*))
import Control.Monad.Except (MonadError, throwError)
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.State (MonadState)
import qualified Data.ByteString.Lazy as BSL
import Data.Functor (($>))
import Language.Dickinson.Error
import Language.Dickinson.Import
import Language.Dickinson.Lexer
import Language.Dickinson.Parser
import Language.Dickinson.Type
import Lens.Micro.Mtl (use, (.=))
parseImportM :: (HasLexerState s, MonadState s m, MonadError (DickinsonError AlexPosn) m, MonadIO m)
=> [FilePath] -- ^ Include path
-> Import AlexPosn
-> m (Dickinson AlexPosn)
parseImportM = liftLexerState .* parseImport
liftLexerState :: (HasLexerState s, MonadState s m)
=> (AlexUserState -> m (AlexUserState, a))
-> m a
liftLexerState fAct = do
lSt <- use lexerStateLens
(st, x) <- fAct lSt
(lexerStateLens .= st) $> x
-- Parse an import. Does NOT perform renaming!
parseImport :: (MonadError (DickinsonError AlexPosn) m, MonadIO m)
=> [FilePath] -- ^ Include path
-> Import AlexPosn
-> AlexUserState -- ^ Lexer state
-> m (AlexUserState, Dickinson AlexPosn)
parseImport is (Import l n) lSt = do
preFp <- resolveImport is n
case preFp of
Just fp -> parseFp fp lSt
Nothing -> throwError $ ModuleNotFound l n
parseFp :: (MonadError (DickinsonError AlexPosn) m, MonadIO m)
=> FilePath -- ^ Source file
-> AlexUserState -- ^ Lexer state
-> m (AlexUserState, Dickinson AlexPosn)
parseFp fp lSt = do
bsl <- liftIO $ BSL.readFile fp
case parseWithCtx bsl lSt of
Right x -> pure x
Left err -> throwError (ParseErr fp err)
parseFpM :: (HasLexerState s, MonadState s m, MonadError (DickinsonError AlexPosn) m, MonadIO m)
=> FilePath -- ^ Source file
-> m (Dickinson AlexPosn)
parseFpM fp = liftLexerState (parseFp fp)