Skip to content

Instantly share code, notes, and snippets.

@dminuoso
Created December 23, 2021 20:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dminuoso/b273e3a00a0542c4dceda3d98fa56cc0 to your computer and use it in GitHub Desktop.
Save dminuoso/b273e3a00a0542c4dceda3d98fa56cc0 to your computer and use it in GitHub Desktop.
newtype Comp e a = Comp { runComp :: ReaderT (CompEnv e) IO a }
data CompEnv a = CompEnv
{ _comp_warnings :: IORef [OdinWarning]
, _comp_errors :: IORef [OdinError]
, _comp_context :: IORef [Msg]
, _comp_config :: Config
, _comp_runflags :: RunFlags
, _comp_env :: a
}
askErrors :: Comp e [OdinError]
askErrors = Comp $ (readIORef . _comp_errors) =<< ask
-- | Condemn an action if it produces any errors.
condemn :: Comp e a -> Comp e a
condemn act = act <* cut
cut :: Comp e ()
cut = do
e <- askErrors
case e of
[] -> pure ()
_xs -> throwIO BailOut
-- | Proceed only if there are no errors. Will error out otherwise.
(>|>) :: Comp e a -> Comp e b -> Comp e b
f >|> g = condemn f >> g
-- | Proceed only if there are no errors. Will error out otherwise.
(>|>=) :: Comp e a -> (a -> Comp e b) -> Comp e b
x >|>= f = condemn x >>= f
-- | Sequence only if there are no errors, skips the other action otherwise.
--
-- This is useful for skipping semantic checks that depend on invariants asserted
-- by an earlier pass.
(>?>) :: Comp e a -> Comp e a -> Comp e a
l >?> r = do
m <- l
e <- askErrors
case e of
[] -> r
_s -> pure m
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment