summaryrefslogtreecommitdiff
path: root/src/GF/Infra/CheckM.hs
blob: 52802d59b5a536d2e85a3e799c4860cc749d2dbb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
----------------------------------------------------------------------
-- |
-- Module      : CheckM
-- Maintainer  : (Maintainer)
-- Stability   : (stable)
-- Portability : (portable)
--
-- > CVS $Date: 2005/02/18 19:21:13 $ 
-- > CVS $Author: peb $
-- > CVS $Revision: 1.4 $
--
-- (Description of the module)
-----------------------------------------------------------------------------

module CheckM (Check,
	       checkError, checkCond, checkWarn, checkUpdate, checkInContext,
	       checkUpdates, checkReset, checkResets, checkGetContext, 
	       checkLookup, checkStart, checkErr, checkVal, checkIn, 
	       prtFail
	      ) where

import Operations
import Grammar
import Ident
import PrGrammar

-- | the strings are non-fatal warnings
type Check a = STM (Context,[String]) a

checkError :: String -> Check a
checkError = raise

checkCond :: String -> Bool -> Check ()
checkCond s b = if b then return () else checkError s

-- | warnings should be reversed in the end
checkWarn :: String -> Check ()
checkWarn s = updateSTM (\ (cont,msg) -> (cont, s:msg))

checkUpdate :: Decl -> Check ()
checkUpdate d = updateSTM (\ (cont,msg) -> (d:cont, msg))

checkInContext :: [Decl] -> Check r -> Check r
checkInContext g ch = do
  i <- checkUpdates g
  r <- ch
  checkResets i
  return r

checkUpdates :: [Decl] -> Check Int
checkUpdates ds = mapM checkUpdate ds >> return (length ds)

checkReset :: Check ()
checkReset = checkResets 1

checkResets :: Int -> Check ()
checkResets i = updateSTM (\ (cont,msg) -> (drop i cont, msg))

checkGetContext :: Check Context
checkGetContext = do
  (co,_) <- readSTM
  return co

checkLookup :: Ident -> Check Type
checkLookup x = do
  co <- checkGetContext
  checkErr $ maybe (prtBad "unknown variable" x) return $ lookup x co

checkStart :: Check a -> Err (a,(Context,[String]))
checkStart c = appSTM c ([],[])

checkErr :: Err a -> Check a
checkErr e = stm (\s -> do
  v <- e
  return (v,s)
  )

checkVal :: a -> Check a
checkVal v = return v

prtFail :: Print a => String -> a -> Check b
prtFail s t = checkErr $ prtBad s t

checkIn :: String -> Check a -> Check a
checkIn msg c = stm $ \s@(g,ws) -> case appSTM c s of
  Bad e -> Bad $ msg ++++ e
  Ok (v,(g',ws')) -> Ok (v,(g',ws2)) where
    new = take (length ws' - length ws) ws'
    ws2 = [msg ++++ w | w <- new] ++ ws