|
| 1 | +{-# LANGUAGE LambdaCase, RecordWildCards #-} |
| 2 | +module Main where |
| 3 | + |
| 4 | +import Data.Maybe ( fromMaybe ) |
| 5 | +import Control.Monad ( unless ) |
| 6 | +import Control.Monad.IO.Class ( MonadIO(liftIO) ) |
| 7 | +import Control.DeepSeq ( NFData(..) ) |
| 8 | + |
| 9 | +import System.Console.GetOpt ( OptDescr(Option), ArgDescr(ReqArg) ) |
| 10 | + |
| 11 | +import Data.Version ( showVersion ) |
| 12 | +import Paths_agda2min ( version ) |
| 13 | + |
| 14 | +import Agda.Syntax.Common.Pretty ( prettyShow ) |
| 15 | +import Agda.Syntax.Internal ( qnameName, qnameModule ) |
| 16 | +import Agda.Syntax.TopLevelModuleName ( TopLevelModuleName, moduleNameToFileName ) |
| 17 | + |
| 18 | +import Agda.Compiler.Common ( curIF, compileDir ) |
| 19 | +import Agda.Compiler.Backend ( Backend(..), Backend'(..), Recompile(..), IsMain ) |
| 20 | + |
| 21 | +import Agda.TypeChecking.Monad.Base ( Definition(..) ) |
| 22 | +import Agda.TypeChecking.Monad |
| 23 | + ( TCM, withCurrentModule, iInsideScope, setScope |
| 24 | + , CompilerPragma(..), getUniqueCompilerPragma ) |
| 25 | + |
| 26 | +import Agda.Main ( runAgda ) |
| 27 | + |
| 28 | +main = runAgda [Backend backend] |
| 29 | + |
| 30 | +data Options = Options { optOutDir :: Maybe FilePath } |
| 31 | + |
| 32 | +instance NFData Options where |
| 33 | + rnf _ = () |
| 34 | + |
| 35 | +outdirOpt :: Monad m => FilePath -> Options -> m Options |
| 36 | +outdirOpt dir opts = return opts{ optOutDir = Just dir } |
| 37 | + |
| 38 | +defaultOptions :: Options |
| 39 | +defaultOptions = Options{ optOutDir = Nothing } |
| 40 | + |
| 41 | +type ModuleEnv = () |
| 42 | +type ModuleRes = () |
| 43 | +type CompiledDef = String |
| 44 | + |
| 45 | +backend :: Backend' Options Options ModuleEnv ModuleRes CompiledDef |
| 46 | +backend = Backend' |
| 47 | + { backendName = "agda2??" |
| 48 | + , backendVersion = Just (showVersion version) |
| 49 | + , options = defaultOptions |
| 50 | + , commandLineFlags = |
| 51 | + [ Option ['o'] ["out-dir"] (ReqArg outdirOpt "DIR") |
| 52 | + "Write output files to DIR. (default: project root)" |
| 53 | + ] |
| 54 | + , isEnabled = \ _ -> True |
| 55 | + , preCompile = return |
| 56 | + , postCompile = \ _ _ _ -> return () |
| 57 | + , preModule = moduleSetup |
| 58 | + , postModule = writeModule |
| 59 | + , compileDef = compile |
| 60 | + , scopeCheckingSuffices = False |
| 61 | + , mayEraseType = \ _ -> return True |
| 62 | + } |
| 63 | + |
| 64 | +moduleSetup :: Options -> IsMain -> TopLevelModuleName -> Maybe FilePath |
| 65 | + -> TCM (Recompile ModuleEnv ModuleRes) |
| 66 | +moduleSetup _ _ m _ = do |
| 67 | + setScope . iInsideScope =<< curIF |
| 68 | + return $ Recompile () |
| 69 | + |
| 70 | +compile :: Options -> ModuleEnv -> IsMain -> Definition -> TCM CompiledDef |
| 71 | +compile opts tlm _ Defn{..} |
| 72 | + = withCurrentModule (qnameModule defName) |
| 73 | + $ getUniqueCompilerPragma "AGDA2??" defName >>= \case |
| 74 | + Nothing -> return [] |
| 75 | + Just (CompilerPragma _ _) -> |
| 76 | + return $ prettyShow (qnameName defName) <> " = " <> prettyShow theDef |
| 77 | + |
| 78 | +writeModule :: Options -> ModuleEnv -> IsMain -> TopLevelModuleName -> [CompiledDef] |
| 79 | + -> TCM ModuleRes |
| 80 | +writeModule opts _ _ m cdefs = do |
| 81 | + outDir <- compileDir |
| 82 | + liftIO $ putStrLn (moduleNameToFileName m "txt") |
| 83 | + let outFile = fromMaybe outDir (optOutDir opts) <> "/" <> moduleNameToFileName m "txt" |
| 84 | + unless (all null cdefs) $ liftIO |
| 85 | + $ writeFile outFile |
| 86 | + $ "*** module " <> prettyShow m <> " ***\n" <> unlines cdefs |
0 commit comments