tidy things up

This commit is contained in:
crumbtoo
2023-11-27 17:29:00 -07:00
parent c0ebd227fc
commit 7f6813beb5
6 changed files with 100 additions and 48 deletions

View File

@@ -1,11 +1,13 @@
{-# LANGUAGE BlockArguments #-} {-# LANGUAGE BlockArguments, LambdaCase #-}
module Main where module Main where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------
import Compiler.RLPC import Compiler.RLPC
import Options.Applicative hiding (ParseError) import Options.Applicative hiding (ParseError)
import Control.Monad import Control.Monad
import Control.Monad.Reader import Control.Monad.Reader
import Data.HashSet qualified as S
import System.IO import System.IO
import System.Exit (exitSuccess)
import Core import Core
import TIM import TIM
import Lens.Micro import Lens.Micro
@@ -28,16 +30,24 @@ options = RLPCOptions
<> help "output dumps to FILE. stderr is used by default" <> help "output dumps to FILE. stderr is used by default"
) )
-- temp. i want gcc/ghc style options -- temp. i want gcc/ghc style options
<*> switch <*> fmap S.fromList # many # option debugFlagReader
( long "dump-evals" ( short 'd'
<> short 'd'
<> help "dump evaluation logs" <> help "dump evaluation logs"
<> metavar "DEBUG FLAG"
) )
<*> some (argument str (metavar "FILES...")) <*> some (argument str (metavar "FILES..."))
where where
infixr 9 # infixr 9 #
f # x = f x f # x = f x
mmany :: (Alternative f, Monoid m) => f m -> f m
mmany v = liftA2 (<>) v (mmany v)
debugFlagReader :: ReadM DebugFlag
debugFlagReader = maybeReader $ Just . \case
"dump-eval" -> DDumpEval
"dump-opts" -> DDumpOpts
main :: IO () main :: IO ()
main = do main = do
opts <- execParser optParser opts <- execParser optParser
@@ -46,14 +56,17 @@ main = do
driver :: RLPCIO () () driver :: RLPCIO () ()
driver = sequence_ driver = sequence_
[ dumpEval [ dshowFlags
, ddumpEval
] ]
whenView :: (MonadReader s m) => Getting Bool s Bool -> m () -> m () dshowFlags :: RLPCIO () ()
whenView l m = view l >>= \a -> when a m dshowFlags = whenFlag flagDDumpOpts do
ask >>= liftIO . print
liftIO $ exitSuccess
dumpEval :: RLPCIO () () ddumpEval :: RLPCIO () ()
dumpEval = whenView rlpcDumpEval do ddumpEval = whenFlag flagDDumpEval do
fs <- view rlpcInputFiles fs <- view rlpcInputFiles
forM_ fs $ \f -> liftIO (readFile f) >>= doProg forM_ fs $ \f -> liftIO (readFile f) >>= doProg
@@ -70,6 +83,6 @@ dumpEval = whenView rlpcDumpEval do
parseProg :: RLPCOptions parseProg :: RLPCOptions
-> String -> String
-> Either (SrcError ParseError) (Program, [SrcError ParseError]) -> Either SrcError (Program, [SrcError])
parseProg o = evalRLPC o . (lexCore >=> parseCoreProg) parseProg o = evalRLPC o . (lexCore >=> parseCoreProg)

View File

@@ -43,6 +43,8 @@ library
-- required for happy -- required for happy
, array , array
, data-default-class , data-default-class
, unordered-containers
, hashable
hs-source-dirs: src hs-source-dirs: src
default-language: GHC2021 default-language: GHC2021
@@ -58,6 +60,7 @@ executable rlpc
, microlens , microlens
, microlens-mtl , microlens-mtl
, mtl , mtl
, unordered-containers
hs-source-dirs: app hs-source-dirs: app
default-language: GHC2021 default-language: GHC2021

View File

@@ -1,5 +1,6 @@
{-# LANGUAGE GeneralisedNewtypeDeriving, StandaloneDeriving #-} {-# LANGUAGE GeneralisedNewtypeDeriving, StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
module Compiler.RLPC module Compiler.RLPC
( RLPC(..) ( RLPC(..)
, RLPCIO , RLPCIO
@@ -7,13 +8,16 @@ module Compiler.RLPC
, addFatal , addFatal
, addWound , addWound
, Severity(..) , Severity(..)
, SrcError(..)
, evalRLPCT , evalRLPCT
, evalRLPCIO , evalRLPCIO
, evalRLPC , evalRLPC
, rlpcLogFile , rlpcLogFile
, rlpcDumpEval , rlpcDebugOpts
, rlpcInputFiles , rlpcInputFiles
, DebugFlag(..)
, whenFlag
, flagDDumpEval
, flagDDumpOpts
) )
where where
@@ -23,6 +27,10 @@ import Control.Monad.Reader
import Control.Monad.Errorful import Control.Monad.Errorful
import Data.Functor.Identity import Data.Functor.Identity
import Data.Default.Class import Data.Default.Class
import GHC.Generics (Generic)
import Data.Hashable (Hashable)
import Data.HashSet (HashSet)
import Data.HashSet qualified as S
import Data.Coerce import Data.Coerce
import Lens.Micro import Lens.Micro
import Lens.Micro.TH import Lens.Micro.TH
@@ -30,7 +38,7 @@ import Lens.Micro.TH
-- TODO: fancy errors -- TODO: fancy errors
newtype RLPCT e m a = RLPC { newtype RLPCT e m a = RLPC {
runRLPCT :: ReaderT RLPCOptions (ErrorfulT (SrcError e) m) a runRLPCT :: ReaderT RLPCOptions (ErrorfulT e m) a
} }
deriving (Functor, Applicative, Monad, MonadReader RLPCOptions) deriving (Functor, Applicative, Monad, MonadReader RLPCOptions)
@@ -42,17 +50,17 @@ type RLPCIO e = RLPCT e IO
evalRLPCT :: RLPCOptions evalRLPCT :: RLPCOptions
-> RLPCT e m a -> RLPCT e m a
-> m (Either (SrcError e) (a, [SrcError e])) -> m (Either e (a, [e]))
evalRLPCT o = runRLPCT >>> flip runReaderT o >>> runErrorfulT evalRLPCT o = runRLPCT >>> flip runReaderT o >>> runErrorfulT
evalRLPC :: RLPCOptions evalRLPC :: RLPCOptions
-> RLPC e a -> RLPC e a
-> Either (SrcError e) (a, [SrcError e]) -> Either e (a, [e])
evalRLPC o m = coerce $ evalRLPCT o m evalRLPC o m = coerce $ evalRLPCT o m
evalRLPCIO :: RLPCOptions evalRLPCIO :: RLPCOptions
-> RLPCIO e a -> RLPCIO e a
-> IO (a, [SrcError e]) -> IO (a, [e])
evalRLPCIO o m = do evalRLPCIO o m = do
m' <- evalRLPCT o m m' <- evalRLPCT o m
case m' of case m' of
@@ -62,26 +70,11 @@ evalRLPCIO o m = do
data RLPCOptions = RLPCOptions data RLPCOptions = RLPCOptions
{ _rlpcLogFile :: Maybe FilePath { _rlpcLogFile :: Maybe FilePath
, _rlpcDumpEval :: Bool , _rlpcDebugOpts :: DebugOpts
, _rlpcInputFiles :: [FilePath] , _rlpcInputFiles :: [FilePath]
} }
deriving Show deriving Show
instance Default RLPCOptions where
def = RLPCOptions
{ _rlpcLogFile = Nothing
, _rlpcDumpEval = False
, _rlpcInputFiles = []
}
data SrcError e = SrcError
{ _errSpan :: (Int, Int, Int)
, _errSeverity :: Severity
, _errDiagnostic :: e
}
deriving instance (Show e) => Show (SrcError e)
data Severity = Error data Severity = Error
| Warning | Warning
| Debug | Debug
@@ -93,12 +86,44 @@ type ErrorDoc = String
class Diagnostic e where class Diagnostic e where
errorDoc :: e -> ErrorDoc errorDoc :: e -> ErrorDoc
makeLenses ''RLPCOptions instance MonadErrorful e (RLPC e) where
makeLenses ''SrcError
pure []
instance MonadErrorful (SrcError e) (RLPC e) where
addWound = RLPC . lift . addWound addWound = RLPC . lift . addWound
addFatal = RLPC . lift . addFatal addFatal = RLPC . lift . addFatal
----------------------------------------------------------------------------------
instance Default RLPCOptions where
def = RLPCOptions
{ _rlpcLogFile = Nothing
, _rlpcDebugOpts = mempty
, _rlpcInputFiles = []
}
type DebugOpts = HashSet DebugFlag
data DebugFlag = DDumpEval
| DDumpOpts
deriving (Show, Eq, Generic)
-- deriving (Hashable)
-- via Generically DebugFlag
instance Hashable DebugFlag
makeLenses ''RLPCOptions
pure []
whenFlag :: (MonadReader s m) => SimpleGetter s Bool -> m () -> m ()
whenFlag l m = asks (^. l) >>= \a -> if a then m else pure ()
-- there's probably a better way to write this. my current knowledge of lenses
-- is too weak.
flagGetter :: DebugFlag -> SimpleGetter RLPCOptions Bool
flagGetter d = to $ \s -> s ^. rlpcDebugOpts & S.member d
flagDDumpEval :: SimpleGetter RLPCOptions Bool
flagDDumpEval = flagGetter DDumpEval
flagDDumpOpts :: SimpleGetter RLPCOptions Bool
flagDDumpOpts = flagGetter DDumpOpts

View File

@@ -4,7 +4,7 @@ module Core
, parseCoreProg , parseCoreProg
, parseCoreExpr , parseCoreExpr
, lexCore , lexCore
, ParseError , SrcError(..)
) )
where where
---------------------------------------------------------------------------------- ----------------------------------------------------------------------------------

View File

@@ -3,7 +3,8 @@ module Core.Lex
( lexCore ( lexCore
, lexCore' , lexCore'
, CoreToken(..) , CoreToken(..)
, ParseError(..) , SrcError(..)
, SrcErrorType(..)
, Located(..) , Located(..)
, AlexPosn(..) , AlexPosn(..)
) )
@@ -119,19 +120,30 @@ data CoreToken = TokenLet
| TokenEOF | TokenEOF
deriving Show deriving Show
data SrcError = SrcError
{ _errSpan :: (Int, Int, Int)
, _errSeverity :: Severity
, _errDiagnostic :: SrcErrorType
}
deriving Show
data SrcErrorType = SrcErrLexical String
| SrcErrParse
deriving Show
type Lexer = AlexInput -> Int -> Alex (Located CoreToken) type Lexer = AlexInput -> Int -> Alex (Located CoreToken)
lexWith :: (String -> CoreToken) -> Lexer lexWith :: (String -> CoreToken) -> Lexer
lexWith f (AlexPn _ y x,_,_,s) l = pure $ Located y x l (f $ take l s) lexWith f (AlexPn _ y x,_,_,s) l = pure $ Located y x l (f $ take l s)
-- | The main lexer driver. -- | The main lexer driver.
lexCore :: String -> RLPC ParseError [Located CoreToken] lexCore :: String -> RLPC SrcError [Located CoreToken]
lexCore s = case m of lexCore s = case m of
Left e -> addFatal err Left e -> addFatal err
where err = SrcError where err = SrcError
{ _errSpan = (0,0,0) -- TODO: location { _errSpan = (0,0,0) -- TODO: location
, _errSeverity = Error , _errSeverity = Error
, _errDiagnostic = ParErrLexical e , _errDiagnostic = SrcErrLexical e
} }
Right ts -> pure ts Right ts -> pure ts
where where
@@ -139,7 +151,7 @@ lexCore s = case m of
-- | @lexCore@, but the tokens are stripped of location info. Useful for -- | @lexCore@, but the tokens are stripped of location info. Useful for
-- debugging -- debugging
lexCore' :: String -> RLPC ParseError [CoreToken] lexCore' :: String -> RLPC SrcError [CoreToken]
lexCore' s = fmap f <$> lexCore s lexCore' s = fmap f <$> lexCore s
where f (Located _ _ _ t) = t where f (Located _ _ _ t) = t

View File

@@ -6,7 +6,6 @@ module Core.Parse
, module Core.Lex -- temp convenience , module Core.Lex -- temp convenience
, parseTmp , parseTmp
, SrcError , SrcError
, ParseError
, Module , Module
) )
where where
@@ -24,7 +23,7 @@ import Data.Default.Class (def)
%name parseCoreProg StandaloneProgram %name parseCoreProg StandaloneProgram
%tokentype { Located CoreToken } %tokentype { Located CoreToken }
%error { parseError } %error { parseError }
%monad { RLPC ParseError } %monad { RLPC SrcError }
%token %token
let { Located _ _ _ TokenLet } let { Located _ _ _ TokenLet }
@@ -126,12 +125,12 @@ Con : '(' consym ')' { $2 }
| conname { $1 } | conname { $1 }
{ {
parseError :: [Located CoreToken] -> RLPC ParseError a parseError :: [Located CoreToken] -> RLPC SrcError a
parseError (Located y x l _ : _) = addFatal err parseError (Located y x l _ : _) = addFatal err
where err = SrcError where err = SrcError
{ _errSpan = (y,x,l) { _errSpan = (y,x,l)
, _errSeverity = Error , _errSeverity = Error
, _errDiagnostic = ParErrParse , _errDiagnostic = SrcErrParse
} }
parseTmp :: IO Module parseTmp :: IO Module