@@ -43,10 +43,17 @@ class (EnvReader m, EnvExtender m, Fallible1 m, IRRep r)
4343 rawEmitDecl :: Emits n => NameHint -> LetAnn -> Expr r n -> m n (AtomVar r n )
4444
4545class Builder r m => ScopableBuilder (r :: IR ) (m :: MonadKind1 ) | m -> r where
46- buildScoped
46+ buildScopedAndThen
4747 :: SinkableE e
4848 => (forall l . (Emits l , DExt n l ) => m l (e l ))
49- -> m n (Abs (Nest (Decl r )) e n )
49+ -> (forall l . DExt n l => Nest (Decl r ) n l -> e l -> m l a )
50+ -> m n a
51+
52+ buildScoped
53+ :: (ScopableBuilder r m , SinkableE e )
54+ => (forall l . (Emits l , DExt n l ) => m l (e l ))
55+ -> m n (Abs (Nest (Decl r )) e n )
56+ buildScoped cont = buildScopedAndThen cont \ decls body -> return $ Abs decls body
5057
5158type SBuilder = Builder SimpIR
5259type CBuilder = Builder CoreIR
@@ -208,21 +215,26 @@ instance ( RenameB frag, HoistableB frag, OutFrag frag
208215 , ExtOutMap Env frag , Fallible m , IRRep r )
209216 => ScopableBuilder r (DoubleBuilderT r frag m ) where
210217 -- TODO: find a safe API for DoubleInplaceT sufficient to implement this
211- buildScoped cont = DoubleBuilderT do
212- (ans, decls ) <- UnsafeMakeDoubleInplaceT $
218+ buildScopedAndThen cont1 cont2 = DoubleBuilderT do
219+ (ans, topDecls ) <- UnsafeMakeDoubleInplaceT $
213220 StateT \ s@ (topScope, _) -> do
214- Abs rdecls (PairE e (LiftE topDecls)) <-
215- locallyMutableInplaceT do
216- (e, (_, topDecls)) <- flip runStateT (topScope, emptyOutFrag) $
217- unsafeRunDoubleInplaceT $ runDoubleBuilderT' do
218- Emits <- fabricateEmitsEvidenceM
219- Distinct <- getDistinct
220- cont
221- return $ PairE e $ LiftE topDecls
222- return ((Abs (unRNest rdecls) e, topDecls), s)
223- unsafeEmitDoubleInplaceTHoisted decls
221+ (ans, topDecls) <- locallyMutableInplaceT
222+ (do (e, s') <- flip runStateT (topScope, emptyOutFrag) $
223+ unsafeRunDoubleInplaceT $ runDoubleBuilderT' do
224+ Emits <- fabricateEmitsEvidenceM
225+ Distinct <- getDistinct
226+ cont1
227+ return $ PairE e $ LiftE s')
228+ (\ rdecls (PairE e (LiftE s')) -> do
229+ (ans, (_, topDecls)) <- flip runStateT s' $
230+ unsafeRunDoubleInplaceT $ runDoubleBuilderT' do
231+ Distinct <- getDistinct
232+ cont2 (unRNest rdecls) e
233+ return (ans, topDecls))
234+ return ((ans, topDecls), s)
235+ unsafeEmitDoubleInplaceTHoisted topDecls
224236 return ans
225- {-# INLINE buildScoped #-}
237+ {-# INLINE buildScopedAndThen #-}
226238
227239-- TODO: derive this instead
228240instance ( IRRep r , RenameB frag , HoistableB frag , OutFrag frag
@@ -385,7 +397,7 @@ instance Fallible m => TopBuilder (TopBuilderT m) where
385397 {-# INLINE emitNamelessEnv #-}
386398
387399 localTopBuilder cont = TopBuilderT $
388- locallyMutableInplaceT $ runTopBuilderT' cont
400+ locallyMutableInplaceT ( runTopBuilderT' cont) ( \ d e -> return $ Abs d e)
389401 {-# INLINE localTopBuilder #-}
390402
391403instance (SinkableV v , TopBuilder m ) => TopBuilder (SubstReaderT v m i ) where
@@ -470,14 +482,12 @@ liftEmitBuilder cont = do
470482 emitDecls $ Abs (unsafeCoerceB $ unRNest decls) result
471483
472484instance (IRRep r , Fallible m ) => ScopableBuilder r (BuilderT r m ) where
473- buildScoped cont = BuilderT do
474- Abs rdecls e <- locallyMutableInplaceT $
475- runBuilderT' do
476- Emits <- fabricateEmitsEvidenceM
477- Distinct <- getDistinct
478- cont
479- return $ Abs (unRNest rdecls) e
480- {-# INLINE buildScoped #-}
485+ buildScopedAndThen cont1 cont2 = BuilderT $ locallyMutableInplaceT
486+ (runBuilderT' do
487+ Emits <- fabricateEmitsEvidenceM
488+ cont1 )
489+ (\ rdecls e -> runBuilderT' $ cont2 (unRNest rdecls) e)
490+ {-# INLINE buildScopedAndThen #-}
481491
482492newtype BuilderDeclEmission (r :: IR ) (n :: S ) (l :: S ) = BuilderDeclEmission (Decl r n l )
483493instance IRRep r => ExtOutMap Env (BuilderDeclEmission r ) where
@@ -504,33 +514,41 @@ instance (IRRep r, Fallible m) => EnvExtender (BuilderT r m) where
504514 {-# INLINE refreshAbs #-}
505515
506516instance (SinkableV v , ScopableBuilder r m ) => ScopableBuilder r (SubstReaderT v m i ) where
507- buildScoped cont = SubstReaderT $ ReaderT \ env ->
508- buildScoped $
509- runReaderT (runSubstReaderT' cont) (sink env)
510- {-# INLINE buildScoped #-}
517+ buildScopedAndThen cont1 cont2 = SubstReaderT $ ReaderT \ env ->
518+ buildScopedAndThen
519+ (runReaderT (runSubstReaderT' cont1) (sink env))
520+ (\ d e -> runReaderT (runSubstReaderT' $ cont2 d e) (sink env))
521+ {-# INLINE buildScopedAndThen #-}
511522
512523instance (SinkableV v , Builder r m ) => Builder r (SubstReaderT v m i ) where
513524 rawEmitDecl hint ann expr = SubstReaderT $ lift $ emitDecl hint ann expr
514525 {-# INLINE rawEmitDecl #-}
515526
516527instance (SinkableE e , ScopableBuilder r m ) => ScopableBuilder r (OutReaderT e m ) where
517- buildScoped cont = OutReaderT $ ReaderT \ env ->
518- buildScoped do
519- env' <- sinkM env
520- runReaderT (runOutReaderT' cont) env'
521- {-# INLINE buildScoped #-}
528+ buildScopedAndThen cont1 cont2 = OutReaderT $ ReaderT \ env ->
529+ buildScopedAndThen
530+ (do env' <- sinkM env
531+ runReaderT (runOutReaderT' cont1) env')
532+ (\ d e -> do
533+ env' <- sinkM env
534+ runReaderT (runOutReaderT' $ cont2 d e) env')
535+ {-# INLINE buildScopedAndThen #-}
522536
523537instance (SinkableE e , Builder r m ) => Builder r (OutReaderT e m ) where
524538 rawEmitDecl hint ann expr =
525539 OutReaderT $ lift $ emitDecl hint ann expr
526540 {-# INLINE rawEmitDecl #-}
527541
528542instance (SinkableE e , ScopableBuilder r m ) => ScopableBuilder r (ReaderT1 e m ) where
529- buildScoped cont = ReaderT1 $ ReaderT \ env ->
530- buildScoped do
531- env' <- sinkM env
532- runReaderT (runReaderT1' cont) env'
533- {-# INLINE buildScoped #-}
543+ buildScopedAndThen cont1 cont2 = ReaderT1 $ ReaderT \ env ->
544+ buildScopedAndThen
545+ (do env' <- sinkM env
546+ runReaderT (runReaderT1' cont1) env')
547+ (\ d e -> do
548+ env' <- sinkM env
549+ runReaderT (runReaderT1' $ cont2 d e) env')
550+
551+ {-# INLINE buildScopedAndThen #-}
534552
535553instance (SinkableE e , Builder r m ) => Builder r (ReaderT1 e m ) where
536554 rawEmitDecl hint ann expr =
@@ -542,11 +560,14 @@ instance (SinkableE e, HoistableState e, Builder r m) => Builder r (StateT1 e m)
542560 {-# INLINE rawEmitDecl #-}
543561
544562instance (SinkableE e , HoistableState e , ScopableBuilder r m ) => ScopableBuilder r (StateT1 e m ) where
545- buildScoped cont = StateT1 \ s -> do
546- Abs decls (e `PairE ` s') <- buildScoped $ liftM toPairE $ runStateT1 cont =<< sinkM s
547- let s'' = hoistState s decls s'
548- return (Abs decls e, s'')
549- {-# INLINE buildScoped #-}
563+ buildScopedAndThen cont1 cont2 = StateT1 \ s1 -> do
564+ buildScopedAndThen
565+ (liftM toPairE $ runStateT1 cont1 =<< sinkM s1)
566+ (\ decls (PairE e s2) -> do
567+ let s3 = hoistState s1 decls s2
568+ (ans, s4) <- runStateT1 (cont2 decls e) (sink s3)
569+ let s5 = hoistState s3 decls s4
570+ return (ans, s5))
550571
551572instance (SinkableE e , HoistableState e , HoistingTopBuilder frag m )
552573 => HoistingTopBuilder frag (StateT1 e m ) where
0 commit comments