@@ -15,6 +15,7 @@ Stability : provisional
15
15
{-# LANGUAGE OverlappingInstances #-}
16
16
#endif
17
17
{-# LANGUAGE OverloadedStrings #-}
18
+ {-# LANGUAGE RankNTypes #-}
18
19
{-# LANGUAGE ScopedTypeVariables #-}
19
20
{-# LANGUAGE TupleSections #-}
20
21
{-# LANGUAGE ViewPatterns #-}
@@ -26,6 +27,7 @@ module SAWScript.Interpreter
26
27
, processFile
27
28
, buildTopLevelEnv
28
29
, primDocEnv
30
+ , InteractiveMonad (.. )
29
31
)
30
32
where
31
33
@@ -262,34 +264,40 @@ stmtInterpreter :: StmtInterpreter
262
264
stmtInterpreter ro rw stmts =
263
265
fst <$> runTopLevel (withLocalEnv emptyLocal (interpretStmts stmts)) ro rw
264
266
265
- processStmtBind :: Bool -> SS. Pattern -> Maybe SS. Type -> SS. Expr -> TopLevel ()
267
+ processStmtBind ::
268
+ InteractiveMonad m =>
269
+ Bool ->
270
+ SS. Pattern ->
271
+ Maybe SS. Type ->
272
+ SS. Expr ->
273
+ m ()
266
274
processStmtBind printBinds pat _mc expr = do -- mx mt
267
275
let (mx, mt) = case pat of
268
276
SS. PWild t -> (Nothing , t)
269
277
SS. PVar x t -> (Just x, t)
270
278
_ -> (Nothing , Nothing )
271
279
let it = SS. Located " it" " it" SS. PosREPL
272
280
let lname = maybe it id mx
273
- let ctx = SS. tContext SS. TopLevel
281
+ ctx <- SS. tContext <$> getMonadContext
274
282
let expr' = case mt of
275
283
Nothing -> expr
276
284
Just t -> SS. TSig expr (SS. tBlock ctx t)
277
285
let decl = SS. Decl (SS. getPos expr) pat Nothing expr'
278
- rw <- getMergedEnv
286
+ rw <- liftTopLevel getMergedEnv
279
287
let opts = rwPPOpts rw
280
288
281
- ~ (SS. Decl _ _ (Just schema) expr'') <-
289
+ ~ (SS. Decl _ _ (Just schema) expr'') <- liftTopLevel $
282
290
either failTypecheck return $ checkDecl (rwTypes rw) (rwTypedef rw) decl
283
291
284
- val <- interpret expr''
292
+ val <- liftTopLevel $ interpret expr''
285
293
286
294
-- Run the resulting TopLevel action.
287
295
(result, ty) <-
288
296
case schema of
289
297
SS. Forall [] t ->
290
298
case t of
291
299
SS. TyCon SS. BlockCon [c, t'] | c == ctx -> do
292
- result <- SAWScript.Value. fromValue val
300
+ result <- actionFromValue val
293
301
return (result, t')
294
302
_ -> return (val, t)
295
303
_ -> fail $ " Not a monomorphic type: " ++ SS. pShow schema
@@ -299,39 +307,70 @@ processStmtBind printBinds pat _mc expr = do -- mx mt
299
307
-- Print non-unit result if it was not bound to a variable
300
308
case pat of
301
309
SS. PWild _ | printBinds && not (isVUnit result) ->
302
- printOutLnTop Info (showsPrecValue opts 0 result " " )
310
+ liftTopLevel $ printOutLnTop Info (showsPrecValue opts 0 result " " )
303
311
_ -> return ()
304
312
305
313
-- Print function type if result was a function
306
314
case ty of
307
- SS. TyCon SS. FunCon _ -> printOutLnTop Info $ getVal lname ++ " : " ++ SS. pShow ty
315
+ SS. TyCon SS. FunCon _ ->
316
+ liftTopLevel $ printOutLnTop Info $ getVal lname ++ " : " ++ SS. pShow ty
308
317
_ -> return ()
309
318
310
- rw' <- getTopLevelRW
311
- putTopLevelRW =<< bindPatternEnv pat (Just (SS. tMono ty)) result rw'
319
+ liftTopLevel $
320
+ do rw' <- getTopLevelRW
321
+ putTopLevelRW =<< bindPatternEnv pat (Just (SS. tMono ty)) result rw'
322
+
323
+
324
+ class (Monad m , MonadFail m ) => InteractiveMonad m where
325
+ liftTopLevel :: TopLevel a -> m a
326
+ withTopLevel :: (forall b . TopLevel b -> TopLevel b ) -> m a -> m a
327
+ actionFromValue :: FromValue a => Value -> m a
328
+ getMonadContext :: m SS. Context
329
+
330
+ instance InteractiveMonad TopLevel where
331
+ liftTopLevel m = m
332
+ withTopLevel f m = f m
333
+ actionFromValue = fromValue
334
+ getMonadContext = return SS. TopLevel
335
+
336
+ instance InteractiveMonad ProofScript where
337
+ liftTopLevel m = scriptTopLevel m
338
+ withTopLevel f (ProofScript m) = ProofScript (underExceptT (underStateT f) m)
339
+ actionFromValue = fromValue
340
+ getMonadContext = return SS. ProofScript
312
341
313
342
-- | Interpret a block-level statement in the TopLevel monad.
314
- interpretStmt ::
343
+ interpretStmt :: InteractiveMonad m =>
315
344
Bool {-^ whether to print non-unit result values -} ->
316
345
SS. Stmt ->
317
- TopLevel ()
346
+ m ()
318
347
interpretStmt printBinds stmt =
319
348
let ? fileReader = BS. readFile in
320
349
case stmt of
321
- SS. StmtBind pos pat mc expr -> withPosition pos (processStmtBind printBinds pat mc expr)
322
- SS. StmtLet _ dg -> do rw <- getTopLevelRW
323
- dg' <- either failTypecheck return $
324
- checkDeclGroup (rwTypes rw) (rwTypedef rw) dg
325
- env <- interpretDeclGroup dg'
326
- withLocalEnv env getMergedEnv >>= putTopLevelRW
327
- SS. StmtCode _ lstr -> do rw <- getTopLevelRW
328
- sc <- getSharedContext
329
- -- io $ putStrLn $ "Processing toplevel code: " ++ show lstr
330
- -- showCryptolEnv
331
- cenv' <- io $ CEnv. parseDecls sc (rwCryptol rw) $ locToInput lstr
332
- putTopLevelRW $ rw { rwCryptol = cenv' }
333
- -- showCryptolEnv
350
+
351
+ SS. StmtBind pos pat mc expr ->
352
+ withTopLevel (withPosition pos) (processStmtBind printBinds pat mc expr)
353
+
354
+ SS. StmtLet _ dg ->
355
+ liftTopLevel $
356
+ do rw <- getTopLevelRW
357
+ dg' <- either failTypecheck return $
358
+ checkDeclGroup (rwTypes rw) (rwTypedef rw) dg
359
+ env <- interpretDeclGroup dg'
360
+ withLocalEnv env getMergedEnv >>= putTopLevelRW
361
+
362
+ SS. StmtCode _ lstr ->
363
+ liftTopLevel $
364
+ do rw <- getTopLevelRW
365
+ sc <- getSharedContext
366
+ -- io $ putStrLn $ "Processing toplevel code: " ++ show lstr
367
+ -- showCryptolEnv
368
+ cenv' <- io $ CEnv. parseDecls sc (rwCryptol rw) $ locToInput lstr
369
+ putTopLevelRW $ rw { rwCryptol = cenv' }
370
+ -- showCryptolEnv
371
+
334
372
SS. StmtImport _ imp ->
373
+ liftTopLevel $
335
374
do rw <- getTopLevelRW
336
375
sc <- getSharedContext
337
376
-- showCryptolEnv
@@ -342,8 +381,10 @@ interpretStmt printBinds stmt =
342
381
putTopLevelRW $ rw { rwCryptol = cenv' }
343
382
-- showCryptolEnv
344
383
345
- SS. StmtTypedef _ name ty -> do rw <- getTopLevelRW
346
- putTopLevelRW $ addTypedef (getVal name) ty rw
384
+ SS. StmtTypedef _ name ty ->
385
+ liftTopLevel $
386
+ do rw <- getTopLevelRW
387
+ putTopLevelRW $ addTypedef (getVal name) ty rw
347
388
348
389
interpretFile :: FilePath -> Bool {- ^ run main? -} -> TopLevel ()
349
390
interpretFile file runMain = do
@@ -414,6 +455,7 @@ buildTopLevelEnv proxy opts =
414
455
, roBasicSS = ss
415
456
, roStackTrace = []
416
457
, roSubshell = fail " Subshells not supported"
458
+ , roProofSubshell = fail " Proof subshells not supported"
417
459
, roLocalEnv = []
418
460
}
419
461
let bic = BuiltinContext {
@@ -464,16 +506,20 @@ processFile ::
464
506
Options ->
465
507
FilePath ->
466
508
Maybe (TopLevel () ) ->
509
+ Maybe (ProofScript () ) ->
467
510
IO ()
468
- processFile proxy opts file mbSubshell = do
511
+ processFile proxy opts file mbSubshell mbProofSubshell = do
469
512
(_, ro, rw) <- buildTopLevelEnv proxy opts
470
513
let ro' = case mbSubshell of
471
514
Nothing -> ro
472
515
Just m -> ro{ roSubshell = m }
516
+ let ro'' = case mbProofSubshell of
517
+ Nothing -> ro'
518
+ Just m -> ro'{ roProofSubshell = m }
473
519
oldpath <- getCurrentDirectory
474
520
file' <- canonicalizePath file
475
521
setCurrentDirectory (takeDirectory file')
476
- _ <- runTopLevel (interpretFile file' True ) ro' rw
522
+ _ <- runTopLevel (interpretFile file' True ) ro'' rw
477
523
`X.catch` (handleException opts)
478
524
setCurrentDirectory oldpath
479
525
return ()
@@ -817,6 +863,11 @@ primitives = Map.fromList
817
863
Experimental
818
864
[]
819
865
866
+ , prim " proof_subshell" " () -> ProofScript ()"
867
+ (\ _ _ -> proofScriptSubshell)
868
+ Experimental
869
+ []
870
+
820
871
, prim " define" " String -> Term -> TopLevel Term"
821
872
(pureVal definePrim)
822
873
Current
0 commit comments