alms-0.4.11: src/ErrorMessage.hs
{-# LANGUAGE
DeriveDataTypeable,
FlexibleInstances,
MultiParamTypeClasses,
QuasiQuotes
#-}
module ErrorMessage (
AlmsException(..), Phase(..), AlmsMonad(..),
almsBug, (!::),
wordsMsg, quoteMsg, pprMsg, showMsg, emptyMsg,
module Message.Quasi,
) where
import Loc
import PprClass
import Message.AST
import Message.Render ()
import Message.Quasi
import Data.Typeable (Typeable)
import Control.Exception (Exception, throwIO, catch)
import Control.Monad.Error (Error(..))
--
-- Representation of Alms errors
--
-- | Alms internal exceptions
data AlmsException
= AlmsException {
exnPhase :: Phase, -- | When did it happen?
exnLoc :: Loc, -- | Where in the source did it happen?
exnMessage :: Message V -- | What happened?
}
deriving Typeable
-- | The phases in which an error might occur:
data Phase
= ParserPhase
| RenamerPhase
| StaticsPhase
| DynamicsPhase
| OtherError String
deriving Show
-- | Error constructors
almsBug :: Phase -> Loc -> String -> String -> AlmsException
almsBug phase loc culprit0 msg0 =
let culprit = if null culprit0
then "unknown"
else culprit0 in
AlmsException (OtherError "BUG! in Alms implementation")
bogus
[$msg|
This shouldn’t happen, so it probably
indicates a bug in the Alms implementation.
<p>
Details:
<dl>
<dt>who: <dd>$words:culprit
<dt>what: <dd>$words:msg0
<dt>where:<dd>$show:loc
<dt>when: <dd>$show:phase
</dl>
<p>
Please report to <exact><tov@ccs.neu.edu></exact>.
|]
(!::) :: Ppr a => String -> a -> Message d
msg0 !:: thing = [$msg| $words:msg0 <q>$thing</q> |]
infix 1 !::
---
--- The AlmsMonad class for carrying alms errors
---
class Monad m => AlmsMonad m where
throwAlms :: AlmsException -> m a
catchAlms :: m a -> (AlmsException -> m a) -> m a
unTryAlms :: m (Either AlmsException a) -> m a
unTryAlms = (>>= either throwAlms return)
instance AlmsMonad IO where
throwAlms = throwIO
catchAlms = Control.Exception.catch
instance AlmsMonad (Either AlmsException) where
throwAlms = Left
catchAlms (Right a) _ = Right a
catchAlms (Left e) k = k e
---
--- Instances
---
instance Ppr AlmsException where
ppr (AlmsException phase loc msg0) =
(text phaseString <+> locString <> colon)
$$
ppr (Indent msg0)
where locString = if isBogus loc
then empty
else text "at" <+> text (show loc)
phaseString = case phase of
ParserPhase -> "Syntax error"
RenamerPhase -> "Type error"
StaticsPhase -> "Type error"
DynamicsPhase -> "Run-time error"
OtherError s -> s
instance Show AlmsException where showsPrec = showFromPpr
instance Exception AlmsException
instance Error AlmsException where
strMsg = AlmsException (OtherError "Error") bogus . Words