1
-- | Lenses for 'TCState' and more.
2
3
module Agda.TypeChecking.Monad.State where
4
5
import Control.Applicative
6
import qualified Control.Exception as E
5
7
import Control.Monad.State
6
8
import Data.Set (Set)
7
9
import Data.Map as Map
8
10
import qualified Data.Set as Set
12
-- import {-# SOURCE #-} Agda.Interaction.Response
13
import Agda.Interaction.Response
14
(InteractionOutputCallback, Response)
10
16
import Agda.Syntax.Common
11
17
import Agda.Syntax.Scope.Base
12
18
import qualified Agda.Syntax.Concrete.Name as C
14
20
import Agda.Syntax.Abstract.Name
16
22
import Agda.TypeChecking.Monad.Base
23
import Agda.TypeChecking.Monad.Base.Benchmark
24
import {-# SOURCE #-} Agda.TypeChecking.Monad.Options
18
26
import Agda.Utils.Hash
27
import Agda.Utils.Monad (bracket_)
28
import Agda.Utils.Pretty
20
30
-- | Resets the non-persistent part of the type checking state.
22
32
resetState :: TCM ()
24
pers <- stPersistent <$> get
34
pers <- gets stPersistent
25
35
put $ initState { stPersistent = pers }
27
37
-- | Resets all of the type checking state.
39
-- Keep only 'Benchmark' information.
29
41
resetAllState :: TCM ()
30
resetAllState = put initState
32
setScope :: ScopeInfo -> TCM ()
33
setScope scope = modify $ \s -> s { stScope = scope }
44
put $ updatePersistentState (\ s -> s { stBenchmark = b }) initState
45
-- resetAllState = put initState
47
-- | Restore 'TCState' after performing subcomputation.
49
-- In contrast to 'Agda.Utils.Monad.localState', the 'Benchmark'
50
-- info from the subcomputation is saved.
51
localTCState :: TCM a -> TCM a
52
localTCState = bracket_ get $ \ s -> do
55
modifyBenchmark $ const b
57
---------------------------------------------------------------------------
58
-- * Lens for persistent state
59
---------------------------------------------------------------------------
61
updatePersistentState :: (PersistentTCState -> PersistentTCState) -> (TCState -> TCState)
62
updatePersistentState f s = s { stPersistent = f (stPersistent s) }
64
modifyPersistentState :: (PersistentTCState -> PersistentTCState) -> TCM ()
65
modifyPersistentState = modify . updatePersistentState
67
---------------------------------------------------------------------------
69
---------------------------------------------------------------------------
35
71
-- | Get the current scope.
36
72
getScope :: TCM ScopeInfo
37
73
getScope = gets stScope
39
getPatternSyns :: TCM PatternSynDefns
40
getPatternSyns = gets stPatternSyns
42
setPatternSyns :: PatternSynDefns -> TCM ()
43
setPatternSyns m = modify $ \s -> s { stPatternSyns = m }
45
modifyPatternSyns :: (PatternSynDefns -> PatternSynDefns) -> TCM ()
46
modifyPatternSyns f = do
50
getPatternSynImports :: TCM PatternSynDefns
51
getPatternSynImports = gets stPatternSynImports
53
lookupPatternSyn :: QName -> TCM PatternSynDefn
54
lookupPatternSyn x = do
56
case Map.lookup x s of
59
si <- getPatternSynImports
60
case Map.lookup x si of
62
Nothing -> typeError $ NotInScope [qnameToConcrete x]
64
setExtLambdaTele :: Map QName (Int , Int) -> TCM ()
65
setExtLambdaTele tele = modify $ \s -> s { stExtLambdaTele = tele }
67
getExtLambdaTele :: TCM (Map QName (Int , Int))
68
getExtLambdaTele = gets stExtLambdaTele
70
addExtLambdaTele :: QName -> (Int , Int) -> TCM ()
71
addExtLambdaTele id x = getExtLambdaTele >>= setExtLambdaTele . (insert id x)
75
-- | Set the current scope.
76
setScope :: ScopeInfo -> TCM ()
77
setScope scope = modifyScope (const scope)
73
79
-- | Modify the current scope.
74
80
modifyScope :: (ScopeInfo -> ScopeInfo) -> TCM ()
81
modifyScope f = modify $ \ s -> s { stScope = f (stScope s) }
79
83
-- | Run a computation in a local scope.
80
84
withScope :: ScopeInfo -> TCM a -> TCM (a, ScopeInfo)
106
notInScope :: C.QName -> TCM a
108
printScope "unbound" 5 ""
109
typeError $ NotInScope [x]
111
-- | Debug print the scope.
112
printScope :: String -> Int -> String -> TCM ()
113
printScope tag v s = verboseS ("scope." ++ tag) v $ do
115
reportSDoc ("scope." ++ tag) v $ return $ vcat [ text s, text $ show scope ]
117
---------------------------------------------------------------------------
118
-- * Top level module
119
---------------------------------------------------------------------------
104
121
-- | Set the top-level module. This affects the global module id of freshly
105
122
-- generated names.
133
154
-- | Get the Haskell imports.
134
155
getHaskellImports :: TCM (Set String)
135
156
getHaskellImports = gets stHaskellImports
158
---------------------------------------------------------------------------
159
-- * Interaction output callback
160
---------------------------------------------------------------------------
162
getInteractionOutputCallback :: TCM InteractionOutputCallback
163
getInteractionOutputCallback
164
= gets $ stInteractionOutputCallback . stPersistent
166
appInteractionOutputCallback :: Response -> TCM ()
167
appInteractionOutputCallback r
168
= getInteractionOutputCallback >>= \ cb -> cb r
170
setInteractionOutputCallback :: InteractionOutputCallback -> TCM ()
171
setInteractionOutputCallback cb
172
= modifyPersistentState $ \ s -> s { stInteractionOutputCallback = cb }
174
---------------------------------------------------------------------------
175
-- * Pattern synonyms
176
---------------------------------------------------------------------------
178
getPatternSyns :: TCM PatternSynDefns
179
getPatternSyns = gets stPatternSyns
181
setPatternSyns :: PatternSynDefns -> TCM ()
182
setPatternSyns m = modifyPatternSyns (const m)
184
-- | Lens for 'stPatternSyns'.
185
modifyPatternSyns :: (PatternSynDefns -> PatternSynDefns) -> TCM ()
186
modifyPatternSyns f = modify $ \s -> s { stPatternSyns = f (stPatternSyns s) }
188
getPatternSynImports :: TCM PatternSynDefns
189
getPatternSynImports = gets stPatternSynImports
191
lookupPatternSyn :: QName -> TCM PatternSynDefn
192
lookupPatternSyn x = do
194
case Map.lookup x s of
197
si <- getPatternSynImports
198
case Map.lookup x si of
200
Nothing -> notInScope $ qnameToConcrete x
202
---------------------------------------------------------------------------
204
---------------------------------------------------------------------------
206
-- | Lens getter for 'Benchmark' from 'TCState'.
207
theBenchmark :: TCState -> Benchmark
208
theBenchmark = stBenchmark . stPersistent
210
-- | Lens map for 'Benchmark'.
211
updateBenchmark :: (Benchmark -> Benchmark) -> TCState -> TCState
212
updateBenchmark f = updatePersistentState $ \ s -> s { stBenchmark = f (stBenchmark s) }
214
-- | Lens getter for 'Benchmark' from 'TCM'.
215
getBenchmark :: TCM Benchmark
216
getBenchmark = gets $ theBenchmark
218
-- | Lens modify for 'Benchmark'.
219
modifyBenchmark :: (Benchmark -> Benchmark) -> TCM ()
220
modifyBenchmark = modify . updateBenchmark
222
-- | Run a fresh instance of the TCM (with initial state).
223
-- 'Benchmark' info is preserved.
224
freshTCM :: TCM a -> TCM (Either TCErr a)
226
-- Prepare an initial state with current benchmark info.
228
let s = updateBenchmark (const b) initState
229
-- Run subcomputation in initial state.
230
-- If we encounter an exception, we lose the state and the
232
-- We could retrieve i from a type error, which carries the state,
233
-- but we do not care for benchmarking in the presence of errors.
234
r <- liftIO $ (Right <$> runTCM initEnv s m) `E.catch` (return . Left)
236
Left err -> return $ Left err
238
-- Keep only the benchmark info from the final state of the subcomp.
239
modifyBenchmark $ const $ theBenchmark s