Files
rlp/app/Main.hs
2024-01-30 16:19:03 -07:00

148 lines
4.2 KiB
Haskell

{-# LANGUAGE BlockArguments, LambdaCase #-}
module Main where
----------------------------------------------------------------------------------
import Compiler.RLPC
import Control.Exception
import Options.Applicative hiding (ParseError)
import Control.Monad
import Control.Monad.Reader
import Data.HashSet qualified as S
import Data.Text (Text)
import Data.Text qualified as T
import Data.Text.IO qualified as TIO
import System.IO
import System.Exit (exitSuccess)
import Core
import TI
import GM
import Lens.Micro.Mtl
----------------------------------------------------------------------------------
optParser :: ParserInfo RLPCOptions
optParser = info (helper <*> options)
( fullDesc
<> progDesc "Compile rl' programs"
<> header "rlpc - The Inglorious rl' Compiler"
)
options :: Parser RLPCOptions
options = RLPCOptions
{- --log, -l -}
<$> optional # strOption
( long "log"
<> short 'l'
<> metavar "FILE"
<> help "output dumps to FILE. stderr is used if unset"
)
{- -d -}
<*> fmap S.fromList # many # option debugFlagReader
( short 'd'
<> help "dump evaluation logs"
<> metavar "DEBUG FLAG"
)
{- --evaluator, -e -}
<*> option evaluatorReader
( long "evaluator"
<> short 'e'
<> metavar "gm|ti"
<> value EvaluatorGM
<> help "the intermediate layer used to model evaluation"
)
<*> option auto
( long "heap-trigger"
<> metavar "INT"
<> help "the number of nodes allowed on the heap before\
\triggering the garbage collector"
<> value 50
)
<*> option languageReader
( long "language"
)
<*> some (argument str $ metavar "FILES...")
where
infixr 9 #
f # x = f x
languageReader :: ReadM Language
languageReader = maybeReader $ \case
"rlp" -> Just LanguageRlp
"core" -> Just LanguageCore
debugFlagReader :: ReadM DebugFlag
debugFlagReader = maybeReader $ Just
evaluatorReader :: ReadM Evaluator
evaluatorReader = maybeReader $ \case
"gm" -> Just EvaluatorGM
"ti" -> Just EvaluatorTI
_ -> Nothing
mmany :: (Alternative f, Monoid m) => f m -> f m
mmany v = liftA2 (<>) v (mmany v)
----------------------------------------------------------------------------------
main :: IO ()
main = do
opts <- execParser optParser
void $ evalRLPCIO opts driver
driver :: RLPCIO ()
driver = sequence_
[ dshowFlags
, ddumpAST
, ddumpEval
]
dshowFlags :: RLPCIO ()
dshowFlags = whenDFlag "dump-flags" do
ask >>= liftIO . print
ddumpAST :: RLPCIO ()
ddumpAST = whenDFlag "dump-ast" $ forFiles_ \o f -> do
liftIO $ withFile f ReadMode $ \h -> do
s <- TIO.hGetContents h
case parseProg o s of
Right (a,_) -> hPutStrLn stderr $ show a
Left e -> error "todo errors lol"
ddumpEval :: RLPCIO ()
ddumpEval = whenDFlag "dump-eval" do
fs <- view rlpcInputFiles
forM_ fs $ \f -> liftIO (TIO.readFile f) >>= doProg
where
doProg :: Text -> RLPCIO ()
doProg = undefined
-- doProg s = ask >>= \o -> case parseProg o s of
-- -- TODO: error handling
-- Left e -> addFatal . CompilerError $ show e
-- Right (a,_) -> do
-- log <- view rlpcLogFile
-- dumpEval <- chooseEval
-- case log of
-- Just f -> liftIO $ withFile f WriteMode $ dumpEval a
-- Nothing -> liftIO $ dumpEval a stderr
-- choose the appropriate model based on the compiler opts
-- chooseEval = do
-- ev <- view rlpcEvaluator
-- pure $ case ev of
-- EvaluatorGM -> v GM.hdbgProg
-- EvaluatorTI -> v TI.hdbgProg
-- where v f p h = f p h *> pure ()
parseProg :: RLPCOptions
-> Text
-> (Maybe Program', [MsgEnvelope RlpcError])
parseProg o = evalRLPC o . (lexCore >=> parseCoreProg)
forFiles_ :: (Monad m)
=> (RLPCOptions -> FilePath -> RLPCT m a)
-> RLPCT m ()
forFiles_ k = do
fs <- view rlpcInputFiles
o <- ask
forM_ fs (k o)