Checks.hs 3.58 KB
Newer Older
Björn Peemöller 's avatar
Björn Peemöller committed
1 2 3 4 5 6 7 8 9 10 11 12 13
{- |
    Module      :  $Header$
    Description :  Different checks on a Curry module
    Copyright   :  (c) 2011, Björn Peemöller (bjp@informatik.uni-kiel.de)
    License     :  OtherLicense

    Maintainer  :  bjp@informatik.uni-kiel.de
    Stability   :  experimental
    Portability :  portable

    This module subsumes the different checks to be performed on a Curry
    module during compilation, e.g. type checking.
-}
Björn Peemöller 's avatar
Björn Peemöller committed
14 15
module Checks where

16
import Control.Monad.Trans.Either
Björn Peemöller 's avatar
Björn Peemöller committed
17
import Curry.Syntax (Module (..), Interface (..))
Björn Peemöller 's avatar
Björn Peemöller committed
18 19

import Base.Messages
Björn Peemöller 's avatar
Björn Peemöller committed
20

Björn Peemöller 's avatar
Björn Peemöller committed
21 22 23 24 25 26 27
import qualified Checks.InterfaceCheck as IC (interfaceCheck)
import qualified Checks.ExportCheck    as EC (exportCheck)
import qualified Checks.KindCheck      as KC (kindCheck)
import qualified Checks.PrecCheck      as PC (precCheck)
import qualified Checks.SyntaxCheck    as SC (syntaxCheck)
import qualified Checks.TypeCheck      as TC (typeCheck)
import qualified Checks.WarnCheck      as WC (warnCheck)
Björn Peemöller 's avatar
Björn Peemöller committed
28 29 30 31

import CompilerEnv
import CompilerOpts

32 33
type Check m = Options -> CompilerEnv -> Module
            -> EitherT [Message] m (CompilerEnv, Module)
Björn Peemöller 's avatar
Björn Peemöller committed
34

Björn Peemöller 's avatar
Björn Peemöller committed
35 36 37 38 39 40 41
interfaceCheck :: CompilerEnv -> Interface -> CheckResult ()
interfaceCheck env intf
  | null errs = return ()
  | otherwise = CheckFailed errs
  where errs = IC.interfaceCheck (opPrecEnv env) (tyConsEnv env)
                                 (valueEnv env) intf

Björn Peemöller 's avatar
Björn Peemöller committed
42
-- |Check the kinds of type definitions and signatures.
43 44 45 46
--
-- * Declarations: Nullary type constructors and type variables are
--                 disambiguated
-- * Environment:  remains unchanged
47 48 49 50
kindCheck :: Monad m => Check m
kindCheck _ env (Module m es is ds)
  | null msgs = right (env, Module m es is ds')
  | otherwise = left msgs
Björn Peemöller 's avatar
Björn Peemöller committed
51
  where (ds', msgs) = KC.kindCheck (moduleIdent env) (tyConsEnv env) ds
Björn Peemöller 's avatar
Björn Peemöller committed
52

Björn Peemöller 's avatar
Björn Peemöller committed
53
-- |Check for a correct syntax.
54 55
--
-- * Declarations: Nullary data constructors and variables are
56
--                 disambiguated, variables are renamed
57
-- * Environment:  remains unchanged
58
syntaxCheck :: Monad m => Check m
Björn Peemöller 's avatar
Björn Peemöller committed
59
syntaxCheck opts env (Module m es is ds)
60 61
  | null msgs = right (env, Module m es is ds')
  | otherwise = left msgs
62 63
  where (ds', msgs) = SC.syntaxCheck opts (moduleIdent env)
                      (valueEnv env) (tyConsEnv env) ds
Björn Peemöller 's avatar
Björn Peemöller committed
64

Björn Peemöller 's avatar
Björn Peemöller committed
65
-- |Check the precedences of infix operators.
66 67 68 69
--
-- * Declarations: Expressions are reordered according to the specified
--                 precedences
-- * Environment:  The operator precedence environment is updated
70 71 72 73
precCheck :: Monad m => Check m
precCheck _ env (Module m es is ds)
  | null msgs = right (env { opPrecEnv = pEnv' }, Module m es is ds')
  | otherwise = left msgs
Björn Peemöller 's avatar
Björn Peemöller committed
74 75 76 77 78
  where (ds', pEnv', msgs) = PC.precCheck (moduleIdent env) (opPrecEnv env) ds

-- |Apply the correct typing of the module.
-- The declarations remain unchanged; the type constructor and value
-- environments are updated.
79 80 81 82
typeCheck :: Monad m => Check m
typeCheck _ env mdl@(Module _ _ _ ds)
  | null msgs = right (env { tyConsEnv = tcEnv', valueEnv = tyEnv' }, mdl)
  | otherwise = left msgs
83 84
  where (tcEnv', tyEnv', msgs) = TC.typeCheck (moduleIdent env)
                                 (tyConsEnv env) (valueEnv env) ds
Björn Peemöller 's avatar
Björn Peemöller committed
85

86
-- |Check the export specification
87 88 89 90
exportCheck :: Monad m => Check m
exportCheck _ env (Module m es is ds)
  | null msgs = right (env, Module m es' is ds)
  | otherwise = left msgs
91 92
  where (es', msgs) = EC.exportCheck (moduleIdent env) (aliasEnv env)
                                     (tyConsEnv env) (valueEnv env) es
93

94
-- TODO: Which kind of warnings?
Björn Peemöller 's avatar
Björn Peemöller committed
95 96

-- |Check for warnings.
97 98
warnCheck :: Options -> CompilerEnv -> Module -> [Message]
warnCheck opts env mdl = WC.warnCheck opts (valueEnv env) (tyConsEnv env) mdl