[project @ 1996-03-19 08:58:34 by partain]
[ghc-hetmet.git] / ghc / compiler / utils / SST.lhs
1 \section{SST: the strict state transformer monad}
2 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3
4 \begin{code}
5 #include "HsVersions.h"
6
7 module SST(
8         SST(..), SST_R, FSST(..), FSST_R,
9
10         _runSST,
11         thenSST, thenSST_, returnSST,
12         thenFSST, thenFSST_, returnFSST, failFSST,
13         recoverFSST, recoverSST, fixFSST,
14
15         MutableVar(..), _MutableArray, 
16         newMutVarSST, readMutVarSST, writeMutVarSST
17   ) where
18
19 import PreludeGlaST( MutableVar(..), _MutableArray(..) )
20
21 CHK_Ubiq() -- debugging consistency check
22 \end{code}
23
24 \begin{code}
25 data SST_R s r = SST_R r (State# s)
26 type SST   s r = State# s -> SST_R s r
27 \end{code}
28
29 \begin{code}
30 -- Type of runSST should be builtin ...
31 -- runSST :: forall r. (forall s. SST s r) -> r
32
33 _runSST :: SST _RealWorld r -> r
34 _runSST m = case m realWorld# of SST_R r s -> r
35
36
37 thenSST :: SST s r -> (r -> State# s -> b) -> State# s -> b
38 {-# INLINE thenSST #-}
39 -- Hence:
40 --      thenSST :: SST s r -> (r -> SST  s r')     -> SST  s r'
41 -- and  thenSST :: SST s r -> (r -> FSST s r' err) -> FSST s r' err
42
43 thenSST m k s = case m s of { SST_R r s' -> k r s' }
44
45 thenSST_ :: SST s r -> (State# s -> b) -> State# s -> b
46 {-# INLINE thenSST_ #-}
47 -- Hence:
48 --      thenSST_ :: SST s r -> SST  s r'     -> SST  s r'
49 -- and  thenSST_ :: SST s r -> FSST s r' err -> FSST s r' err
50
51 thenSST_ m k s = case m s of { SST_R r s' -> k s' }
52
53 returnSST :: r -> SST s r
54 {-# INLINE returnSST #-}
55 returnSST r s = SST_R r s
56 \end{code}
57
58
59 \section{FSST: the failable strict state transformer monad}
60 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
62 \begin{code}
63 data FSST_R s r err = FSST_R_OK   r   (State# s)
64                     | FSST_R_Fail err (State# s)
65
66 type FSST   s r err = State# s -> FSST_R s r err
67 \end{code}
68
69 \begin{code}
70 thenFSST :: FSST s r err -> (r -> FSST s r' err) -> FSST s r' err
71 {-# INLINE thenFSST #-}
72 thenFSST m k s = case m s of
73                    FSST_R_OK r s'     -> k r s'
74                    FSST_R_Fail err s' -> FSST_R_Fail err s'
75
76 thenFSST_ :: FSST s r err -> FSST s r' err -> FSST s r' err
77 {-# INLINE thenFSST_ #-}
78 thenFSST_ m k s = case m s of
79                     FSST_R_OK r s'     -> k s'
80                     FSST_R_Fail err s' -> FSST_R_Fail err s'
81
82 returnFSST :: r -> FSST s r err
83 {-# INLINE returnFSST #-}
84 returnFSST r s = FSST_R_OK r s
85
86 failFSST    :: err -> FSST s r err
87 {-# INLINE failFSST #-}
88 failFSST err s = FSST_R_Fail err s
89
90 recoverFSST :: (err -> FSST s r err)
91             -> FSST s r err
92             -> FSST s r err
93 recoverFSST recovery_fn m s
94   = case m s of 
95         FSST_R_OK r s'     -> FSST_R_OK r s'
96         FSST_R_Fail err s' -> recovery_fn err s'
97
98 recoverSST :: (err -> SST s r)
99             -> FSST s r err
100             -> SST s r
101 recoverSST recovery_fn m s
102   = case m s of 
103         FSST_R_OK r s'     -> SST_R r s'
104         FSST_R_Fail err s' -> recovery_fn err s'
105
106 fixFSST :: (r -> FSST s r err) -> FSST s r err
107 fixFSST m s = result
108             where
109               result           = m loop s
110               FSST_R_OK loop _ = result
111 \end{code}
112
113 Mutables
114 ~~~~~~~~
115 Here we implement mutable variables.  ToDo: get rid of the array impl.
116
117 \begin{code}
118 newMutVarSST :: a -> SST s (MutableVar s a)
119 newMutVarSST init s#
120   = case (newArray# 1# init s#)     of { StateAndMutableArray# s2# arr# ->
121     SST_R (_MutableArray vAR_IXS arr#) s2# }
122   where
123     vAR_IXS = error "Shouldn't access `bounds' of a MutableVar\n"
124
125 readMutVarSST :: MutableVar s a -> SST s a
126 readMutVarSST (_MutableArray _ var#) s#
127   = case readArray# var# 0# s#  of { StateAndPtr# s2# r ->
128     SST_R r s2# }
129
130 writeMutVarSST :: MutableVar s a -> a -> SST s ()
131 writeMutVarSST (_MutableArray _ var#) val s#
132   = case writeArray# var# 0# val s# of { s2# ->
133     SST_R () s2# }
134 \end{code}
135