inch-0.2.0: src/Language/Inch/File.lhs
> {-# LANGUAGE ScopedTypeVariables #-}
> module Language.Inch.File where
> import Prelude
> import qualified Control.Exception as E
> import Control.Monad.State
> import System.Exit
> import System.FilePath
> import System.IO
> import Paths_inch (getDataFileName)
> import Language.Inch.Context
> import Language.Inch.Syntax
> import Language.Inch.ModuleSyntax
> import Language.Inch.Parser
> import Language.Inch.PrettyPrinter
> import Language.Inch.ProgramCheck
> import Language.Inch.Erase
> checkFile :: FilePath -> String -> IO (Module, ZipState)
> checkFile original s = do
> md <- parseModuleIO
> ds <- readImports (fst (splitFileName original)) (modImports md)
> checkModuleIO md ds
> where
> parseModuleIO = case parseModule original s of
> Right md -> return md
> Left err -> putStrLn ("parse error:\n" ++ show err) >> exitFailure
>
> checkModuleIO md ds = case runStateT (checkModule md ds) initialState of
> Right x -> return x
> Left err -> putStrLn ("type-checking failed:\n" ++ renderMe err) >> exitFailure
> eraseWrite :: FilePath -> Module -> ZipState -> IO ()
> eraseWrite output md st = case evalStateT (eraseModule md) st of
> Right md' -> writeFile output (renderMe (fog md'))
> Left err -> putStrLn ("erase error:\n" ++ renderMe err) >> exitFailure
> getInterface :: Module -> String
> getInterface = renderMe . map fog . filter interfaceDecl . modDecls
> where
> interfaceDecl (DataDecl _ _ _ _) = True
> interfaceDecl (TypeDecl _ _) = True
> interfaceDecl (CDecl _ _) = True
> interfaceDecl (IDecl _ _) = True
> interfaceDecl (Decl (SigDecl _ _)) = True
> interfaceDecl (Decl (FunDecl _ _)) = False
> readImport :: FilePath -> Import -> IO [STopDeclaration]
> readImport dir im = do
> s <- E.catch (readFile (combine dir inchFile)) $ \ (_ :: E.IOException) ->
> E.catch (readFile =<< getDataFileName inchFile) $ \ (_ :: E.IOException) ->
> hPutStrLn stderr ("Could not load " ++ inchFile) >> return ""
> case parseInterface inchFile s of
> Right ds -> return $ filter (included . topDeclName) ds
> Left err -> putStrLn ("interface parse error:\n" ++ show err) >> exitFailure
> where
> inchFile = importName im ++ ".inch"
> included x = case impSpec im of
> ImpAll -> True
> Imp ys -> x `elem` ys
> ImpHiding ys -> x `notElem` ys
> readImports :: FilePath -> [Import] -> IO [STopDeclaration]
> readImports dir is = fmap join (mapM (readImport dir) is')
> where
> is' = if any (("Prelude" ==) . importName) is then is
> else Import False "Prelude" Nothing ImpAll : is