Added a value to indicate what type a warning is (to support future configurability) and streamlined the warning functions

This commit is contained in:
Neil Brown 2008-11-13 15:36:22 +00:00
parent 95f6ef2889
commit 0d486f108f
7 changed files with 40 additions and 20 deletions

View File

@ -179,7 +179,7 @@ addCalls
systemFunc :: String -> AAM Int systemFunc :: String -> AAM Int
systemFunc func systemFunc func
= do lift $ addPlainWarning $ "Unknown function " ++ func ++ "; allocating " ++ show unknownSize ++ " bytes stack" = do lift $ warnPlainP WarnInternal $ "Unknown function " ++ func ++ "; allocating " ++ show unknownSize ++ " bytes stack"
return unknownSize return unknownSize
userFunc :: FunctionInfo -> AAM Int userFunc :: FunctionInfo -> AAM Int

View File

@ -236,7 +236,7 @@ checkInitVar m graph startNode
-- The read-from set should be a subset of the written-to set: -- The read-from set should be a subset of the written-to set:
if filterPlain' v `isSubsetOf` filterPlain' vs then return () else if filterPlain' v `isSubsetOf` filterPlain' vs then return () else
do vars <- showCodeExSet $ filterPlain' v `difference` filterPlain' vs do vars <- showCodeExSet $ filterPlain' v `difference` filterPlain' vs
addWarning (getMeta n) $ "Variable(s) read from are not written to before-hand: " ++ vars warnP (getMeta n) WarnUninitialisedVariable $ "Variable(s) read from are not written to before-hand: " ++ vars
checkParAssignUsage :: forall m t. (CSMR m, Die m, MonadIO m, Data t) => t -> m () checkParAssignUsage :: forall m t. (CSMR m, Die m, MonadIO m, Data t) => t -> m ()
checkParAssignUsage = mapM_ checkParAssign . listify isParAssign checkParAssignUsage = mapM_ checkParAssign . listify isParAssign

View File

@ -129,7 +129,7 @@ type TestM = ReaderT CompState (Either String)
instance Die TestM where instance Die TestM where
dieReport (_,s) = throwError s dieReport (_,s) = throwError s
instance Warn TestM where instance Warn TestM where
warnReport (_,s) = throwError s warnReport (_,_,s) = throwError s
buildTestFlowGraph :: [(Int, [Var], [Var])] -> [(Int, Int, EdgeLabel)] -> Int -> Int -> String -> FlowGraph TestM UsageLabel buildTestFlowGraph :: [(Int, [Var], [Var])] -> [(Int, Int, EdgeLabel)] -> Int -> Int -> String -> FlowGraph TestM UsageLabel
buildTestFlowGraph ns es start end v buildTestFlowGraph ns es start end v

View File

@ -17,9 +17,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
-} -}
-- | Error handling and reporting. -- | Error handling and reporting.
module Errors (addPlainWarning, addWarning, checkJust, Die(..), module Errors (checkJust, Die(..),
dieInternal, dieIO, dieP, ErrorReport, dieInternal, dieIO, dieP, ErrorReport,
showWarnings, Warn(..), WarningReport, warnP) where showWarnings, Warn(..), WarningReport, warnP, warnPlainP, WarningType(..), describeWarning) where
import Control.Monad.Error import Control.Monad.Error
import Control.Monad.Trans import Control.Monad.Trans
@ -42,22 +42,40 @@ class Monad m => Die m where
dieP :: Die m => Meta -> String -> m a dieP :: Die m => Meta -> String -> m a
dieP m s = dieReport (Just m,s) dieP m s = dieReport (Just m,s)
type WarningReport = (Maybe Meta, String)
data WarningType
= WarnInternal
| WarnParserOddity
| WarnUnknownPreprocessorDirective
| WarnUninitialisedVariable
| WarnUnusedVariable
deriving (Eq, Show, Ord, Read, Enum, Bounded)
-- I intend the above warnings to be part of a command-line mechanism to enable
-- or suppress them according to various flags. So that you might write:
-- -WnoWarnParserOddity
-- For which we can do a tiny bit of parsing, and use the Read instance to help,
-- as well as using the Enum and Bounded instances to easily discover all warnings
describeWarning :: WarningType -> String
describeWarning WarnInternal = "Internal compiler problems"
describeWarning WarnParserOddity = "Strange things in your code that indicate possible errors"
describeWarning WarnUnknownPreprocessorDirective = "Unrecognised preprocessor directive"
describeWarning WarnUninitialisedVariable = "A variable that is read from before being written to"
describeWarning WarnUnusedVariable = "A variable that is declared but never used"
type WarningReport = (Maybe Meta, WarningType, String)
class Monad m => Warn m where class Monad m => Warn m where
warnReport :: WarningReport -> m () warnReport :: WarningReport -> m ()
warnP :: Warn m => Meta -> String -> m ()
warnP m s = warnReport (Just m,s)
--{{{ warnings --{{{ warnings
-- | Add a warning with no source position. -- | Add a warning with no source position.
addPlainWarning :: Warn m => String -> m () warnPlainP :: Warn m => WarningType -> String -> m ()
addPlainWarning msg = warnReport (Nothing, msg) warnPlainP t msg = warnReport (Nothing, t, msg)
-- | Add a warning. -- | Add a warning.
addWarning :: Warn m => Meta -> String -> m () warnP :: Warn m => Meta -> WarningType -> String -> m ()
addWarning m s = warnReport (Just m, s) warnP m t s = warnReport (Just m, t, s)
--}}} --}}}
-- | Wrapper around error that gives nicer formatting, and prints out context -- | Wrapper around error that gives nicer formatting, and prints out context
@ -112,8 +130,10 @@ printError s = error $ "Error: " ++ s ++ "\n"
showWarnings :: MonadIO m => [WarningReport] -> m () showWarnings :: MonadIO m => [WarningReport] -> m ()
showWarnings = mapM_ printWarning showWarnings = mapM_ printWarning
where where
printWarning (Just m, s) = liftIO $ hPutStrLn stderr $ show m ++ " " ++ s printWarning (Just m, t, s)
printWarning (Nothing, s) = liftIO $ hPutStrLn stderr s = liftIO $ hPutStrLn stderr $ show m ++ " " ++ show t ++ " " ++ s
printWarning (Nothing, t, s)
= liftIO $ hPutStrLn stderr (show t ++ " " ++ s)
-- | Fail after an internal error. -- | Fail after an internal error.

View File

@ -31,7 +31,7 @@ import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified AST as A import qualified AST as A
import Errors (Die, dieP, ErrorReport, Warn, warnP) import Errors (Die, dieP, ErrorReport, Warn, WarningType, warnP)
import Metadata import Metadata
import OrdAST () import OrdAST ()
import UnifyType import UnifyType
@ -376,8 +376,8 @@ makeNonceVariable s m t am
diePC :: (CSMR m, Die m) => Meta -> m String -> m a diePC :: (CSMR m, Die m) => Meta -> m String -> m a
diePC m str = str >>= (dieP m) diePC m str = str >>= (dieP m)
warnPC :: (CSMR m, Warn m) => Meta -> m String -> m () warnPC :: (CSMR m, Warn m) => Meta -> WarningType -> m String -> m ()
warnPC m str = str >>= (warnP m) warnPC m t str = str >>= (warnP m t)
--dieC :: (CSM m, Die m) => m String -> m a --dieC :: (CSM m, Die m) => m String -> m a
--dieC str = str >>= die --dieC str = str >>= die

View File

@ -318,7 +318,7 @@ maybeIndentedList m msg inner
vs <- many1 inner vs <- many1 inner
outdent outdent
return vs return vs
<|> do addWarning m msg <|> do warnP m WarnParserOddity msg
return [] return []
handleSpecs :: OccParser [NameSpec] -> OccParser a -> (Meta -> A.Specification -> a -> a) -> OccParser a handleSpecs :: OccParser [NameSpec] -> OccParser a -> (Meta -> A.Specification -> a -> a) -> OccParser a

View File

@ -141,7 +141,7 @@ handleDirective m s x
-- currently we support so few preprocessor directives that this is more -- currently we support so few preprocessor directives that this is more
-- useful. -- useful.
lookup s [] lookup s []
= do addWarning m "Unknown preprocessor directive ignored" = do warnP m WarnUnknownPreprocessorDirective "Unknown preprocessor directive ignored"
return return return return
lookup s ((re, func):ds) lookup s ((re, func):ds)
= case matchRegex re s of = case matchRegex re s of