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