{- | Module : $Header$ Description : Checks extensions Copyright : (c) 2016 Finn Teegen License : BSD-3-clause Maintainer : bjp@informatik.uni-kiel.de Stability : experimental Portability : portable First of all, the compiler scans a source file for file-header pragmas that may activate language extensions. -} module Checks.ExtensionCheck (extensionCheck) where import qualified Control.Monad.State as S (State, execState, modify) import Curry.Base.Position import Curry.Base.Pretty import Curry.Syntax import Base.Messages (Message, posMessage) import CompilerOpts extensionCheck :: Options -> Module a -> ([KnownExtension], [Message]) extensionCheck opts mdl = execEXC (checkModule mdl) initState where initState = EXCState (optExtensions opts) [] type EXCM = S.State EXCState data EXCState = EXCState { extensions :: [KnownExtension] , errors :: [Message] } execEXC :: EXCM a -> EXCState -> ([KnownExtension], [Message]) execEXC ecm s = let s' = S.execState ecm s in (extensions s', reverse $ errors s') enableExtension :: KnownExtension -> EXCM () enableExtension e = S.modify $ \s -> s { extensions = e : extensions s } report :: Message -> EXCM () report msg = S.modify $ \s -> s { errors = msg : errors s } ok :: EXCM () ok = return () -- The extension check iterates over all given pragmas in the module and -- gathers all extensions mentioned in a language pragma. An error is reported -- if an extension is unknown. checkModule :: Module a -> EXCM () checkModule (Module _ ps _ _ _ _) = mapM_ checkPragma ps checkPragma :: ModulePragma -> EXCM () checkPragma (LanguagePragma _ exts) = mapM_ checkExtension exts checkPragma (OptionsPragma _ _ _) = ok checkExtension :: Extension -> EXCM () checkExtension (KnownExtension _ e) = enableExtension e checkExtension (UnknownExtension p e) = report $ errUnknownExtension p e -- --------------------------------------------------------------------------- -- Error messages -- --------------------------------------------------------------------------- errUnknownExtension :: Position -> String -> Message errUnknownExtension p e = posMessage p $ text "Unknown language extension:" <+> text e