1- {-# LANGUAGE DerivingVia, GeneralizedNewtypeDeriving, OverloadedStrings #-}
1+ {-# LANGUAGE DerivingVia, GeneralizedNewtypeDeriving, OverloadedStrings, DeriveFunctor, DeriveTraversable #-}
22-- | Compilation monad.
33module Agda2Lambox.Compile.Monad
44 ( CompileM
@@ -7,6 +7,7 @@ module Agda2Lambox.Compile.Monad
77 , genericError
88 , genericDocError
99 , internalError
10+ , CompiledItem (.. )
1011 ) where
1112
1213import Control.Monad ( unless )
@@ -18,7 +19,7 @@ import Queue.Ephemeral ( EphemeralQueue(..) )
1819import Queue.Ephemeral qualified as Queue
1920
2021import Agda.Syntax.Abstract (QName )
21- import Agda.Compiler.Backend (getConstInfo , PureTCM , HasConstInfo , HasBuiltins )
22+ import Agda.Compiler.Backend (getConstInfo , PureTCM , HasConstInfo , HasBuiltins , canonicalName )
2223import Agda.TypeChecking.Monad (MonadDebug , MonadTrace , MonadAddContext )
2324import Agda.TypeChecking.Monad.Debug (MonadDebug , reportSDoc )
2425import Agda.TypeChecking.Monad.Base hiding (initState )
@@ -32,6 +33,8 @@ data CompileState = CompileState
3233 -- ^ Names that we have seen, either already compiled or in the queue.
3334 , compileQueue :: EphemeralQueue QName
3435 -- ^ Compilation queue.
36+ , requiredDefs :: Set QName
37+ -- ^ (Locally) required definitions.
3538 }
3639
3740-- NOTE(flupe):
@@ -44,6 +47,7 @@ initState :: [QName] -> CompileState
4447initState qs = CompileState
4548 { seenDefs = Set. fromList qs
4649 , compileQueue = Queue. fromList qs
50+ , requiredDefs = Set. empty
4751 }
4852
4953-- | Backend compilation monad.
@@ -56,6 +60,12 @@ newtype CompileM a = Compile (StateT CompileState TCM a)
5660-- | Require a definition to be compiled.
5761requireDef :: QName -> CompileM ()
5862requireDef q = Compile $ do
63+ q <- liftTCM $ canonicalName q
64+
65+
66+ -- add name to the required list
67+ modify \ s -> s { requiredDefs = Set. insert q (requiredDefs s) }
68+
5969 seen <- gets seenDefs
6070
6171 -- a name is only added to the queue if we haven't seen it yet
@@ -76,15 +86,35 @@ nextUnit = Compile $
7686 Empty -> pure Nothing
7787 Full q queue -> Just q <$ modify \ s -> s { compileQueue = queue }
7888
89+ data CompiledItem a = CompiledItem
90+ { itemName :: QName
91+ , itemDeps :: [QName ]
92+ , itemValue :: a
93+ } deriving (Functor , Foldable , Traversable )
94+
95+ -- | Record the required definitions of a compilation unit.
96+ trackDeps :: CompileM a -> CompileM (a , [QName ])
97+ trackDeps (Compile c) = Compile do
98+ modify \ s -> s {requiredDefs = Set. empty}
99+ x <- c
100+ deps <- gets requiredDefs
101+ pure (x, Set. toList deps)
102+
79103-- | Run the processing function as long as there are names to be compiled.
80104compileLoop
81- :: (Definition -> CompileM ( Maybe a ) ) -- ^ The compilation function
105+ :: forall a . (Definition -> CompileM a ) -- ^ The compilation function
82106 -> [QName ] -- ^ Names to compile
83- -> TCM [a ]
107+ -> TCM [CompiledItem a ]
84108compileLoop step = evalStateT unloop . initState
85109 where
110+ loop :: CompileM [CompiledItem a ]
86111 loop@ (Compile unloop) = nextUnit >>= \ case
87112 Nothing -> pure []
88113 Just q -> do
89- mr <- step =<< (liftTCM $ getConstInfo q)
90- mcons mr <$> loop
114+ (mr, deps) <- trackDeps . step =<< (liftTCM $ getConstInfo q)
115+ let item = CompiledItem
116+ { itemName = q
117+ , itemDeps = deps
118+ , itemValue = mr
119+ }
120+ (item: ) <$> loop
0 commit comments