perga/lib/Preprocessor.hs

36 lines
1.2 KiB
Haskell
Raw Normal View History

module Preprocessor where
import Control.Monad.Except
import qualified Data.Text as T
import System.FilePath
newtype PreprocessorError = ParseError Text
2024-11-22 19:44:31 -08:00
instance ToText PreprocessorError where
toText (ParseError t) = "Preprocessor error on line '" <> t <> "'"
instance ToString PreprocessorError where
toString = toString . toText
type Result = Either PreprocessorError
type ResultIO = ExceptT PreprocessorError IO
concatMapM :: (Applicative f) => (a -> f Text) -> [a] -> f Text
concatMapM _ [] = pure mempty
concatMapM f (x : xs) = ((<>) . (<> "\n") <$> f x) <*> concatMapM f xs
preprocess :: String -> ResultIO Text
preprocess filename = do
2024-11-22 19:44:31 -08:00
text <- decodeUtf8With lenientDecode <$> readFileBS filename
result <- concatMapM (preprocessLine $ takeDirectory filename) (lines text)
putStrLn $ "loading: " ++ filename
pure result
parseInclude :: Text -> Result Text
2024-11-22 19:44:31 -08:00
parseInclude line = maybeToRight (ParseError line) $ T.stripPrefix "@include " line
preprocessLine :: FilePath -> Text -> ResultIO Text
preprocessLine base line
2024-11-22 19:44:31 -08:00
| "@include " `T.isPrefixOf` line = liftEither (parseInclude line) >>= preprocess . normalise . (base </>) . toString
| otherwise = pure line