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
90
91
92
93
94
95
96
97
98
99
100
101
102
|
module CPP.ICode.ParseMonad where
import CPP.ICode.ParseError
import CPP.ICode.ParseWarning
import CPP.ICode.ParsePos
newtype PM a = PM (WM (PR a))
instance Functor PM where
fmap = liftPM
instance Applicative PM where
pure = cleanPM
instance Monad PM where
return = cleanPM
(>>=) = bindPM
warnPM :: PR a -> [Warning] -> PM a
warnPM x w = PM (returnWM x w)
bindPM :: PM a -> (a -> PM b) -> PM b
bindPM (PM m) f = PM $ bindWM m $ \b -> case b of
Errors p -> cleanWM (Errors p)
OK x -> case f x of
PM a -> a
liftPM :: (a -> b) -> PM a -> PM b
liftPM f m = bindPM m (cleanPM . f)
cleanPM :: a -> PM a
cleanPM x = warnOKPM x []
warnOKPM :: a -> [Warning] -> PM a
warnOKPM x = warnPM (okPR x)
throwPM :: Pos -> String -> PM _
throwPM p s = PM $ cleanWM (throwPMsg p s)
throwMultiPM :: Pos -> [String] -> PM _
throwMultiPM p strs = PM $ cleanWM (throwPR (map (\s -> (PError p s)) strs))
singlePM :: a -> Warning -> PM a
singlePM x w = warnOKPM x [w]
discardWarningsPM :: PM a -> PR a
discardWarningsPM (PM a) = discardWarnings a
getWarningsPM :: PM a -> [Warning]
getWarningsPM (PM a) = getWarnings a
mapWarnsPM :: (Warning -> Warning) -> PM a -> PM a
mapWarnsPM f (PM a) = PM $ mapWarns f a
crumplePM :: PM (PM a) -> PM a
crumplePM m = bindPM m id
swapIOPM :: PM (IO a) -> IO (PM a)
swapIOPM m = swapIOPR (discardWarningsPM m)
>>= return . flip warnPM (getWarningsPM m)
sequencePM :: [PM a] -> PM [a]
sequencePM ms = warnPM (sequencePR (map discardWarningsPM ms))
(foldr (++) [] (map getWarningsPM ms))
fstPM :: PM (a,b) -> PM a
fstPM = liftPM fst
sndPM :: PM (a,b) -> PM b
sndPM = liftPM snd
combinePMs :: (a -> b -> c) -> PM a -> PM b -> PM c
combinePMs f (PM p1) (PM p2) = warnPM (combinePRs f (discardWarnings p1)
(discardWarnings p2))
(concatWarns p1 p2)
where
concatWarns (WM _ w1) (WM _ w2) = w1 ++ w2
|