@@ -4,7 +4,8 @@ module Agda2Lambox.Compile.Function
44 ( compileFunction
55 ) where
66
7- import Control.Monad ( forM , when )
7+ import Control.Monad ( forM , when , filterM , unless )
8+ import Control.Monad.IO.Class ( liftIO )
89import Data.List ( elemIndex )
910import Data.Maybe ( isNothing , fromMaybe )
1011
@@ -15,7 +16,7 @@ import Agda.Compiler.Backend ( getConstInfo, funInline )
1516import Agda.Syntax.Treeless ( EvaluationStrategy (EagerEvaluation ) )
1617import Agda.Syntax.Common.Pretty ( prettyShow )
1718import Agda.Syntax.Common ( hasQuantityω )
18- import Agda.Utils.Monad (guardWithError )
19+ import Agda.Utils.Monad (guardWithError , whenM )
1920import Agda.Utils.Lens ( (^.) )
2021
2122import Agda.Utils ( etaExpandCtor )
@@ -32,8 +33,11 @@ isFunction _ = False
3233
3334-- | Convert a function body to a Lambdabox term.
3435compileFunctionBody :: [QName ] -> Definition -> TCM LBox. Term
35- compileFunctionBody ms Defn {defName} = do
36- Just t <- toTreeless EagerEvaluation defName
36+ compileFunctionBody ms Defn {defName, theDef} = do
37+ liftIO $ putStrLn $ prettyShow defName
38+ let Function {funWith} = theDef
39+ liftIO $ print funWith
40+ Just t <- toTreeless EagerEvaluation defName
3741 compileTerm ms =<< etaExpandCtor t
3842
3943
@@ -42,33 +46,39 @@ shouldCompileFunction :: Definition -> Bool
4246shouldCompileFunction def@ Defn {theDef} | Function {.. } <- theDef
4347 = not (theDef ^. funInline) -- not inlined (from module application)
4448 && isNothing funExtLam -- not a pattern-lambda-generated function (inlined by the treeless translation)
45- && isNothing funWith -- not a with-generated function NOTE(flupe): ?
49+ && isNothing funWith -- not a with-generated function (inlined by the treeless translation)
4650 && hasQuantityω def -- non-erased
4751
4852
4953-- | Convert a function definition to a λ□ declaration.
5054compileFunction :: Definition -> TCM (Maybe LBox. GlobalDecl )
5155compileFunction defn | not (shouldCompileFunction defn) = return Nothing
52- compileFunction defn@ Defn {defName, theDef} = do
53- let Function {funMutual = Just ms } = theDef
56+ compileFunction defn@ Defn {theDef} = do
57+ let Function {funMutual = Just mutuals } = theDef
5458
55- -- if the function is at most recursive with itself, just compile body
56- if null ms then
57- Just . LBox. ConstantDecl . Just <$> compileFunctionBody [] defn
59+ defs <- mapM getConstInfo mutuals
5860
59- -- otherwise, take fixpoint
60- else do
61- mdefs :: [Definition ] <- mapM getConstInfo ms
61+ unless (all isFunction defs) $
62+ fail " only mutually defined functions are supported."
6263
63- when (any (not . isFunction) mdefs) $ fail " only mutually defined functions are supported."
64+ -- the mutual functions that we actually compile
65+ -- (so no with-generated functions, etc...)
66+ let mdefs = filter shouldCompileFunction defs
6467
65- let k = fromMaybe 0 $ elemIndex defName ms
68+ -- if the function is not recursive, just compile the body
69+ if null mdefs then Just . LBox. ConstantDecl . Just <$> compileFunctionBody [] defn
6670
67- Just . LBox. ConstantDecl . Just . flip LBox. LFix k <$>
68- forM mdefs \ def@ Defn {defName} -> do
69- body <- compileFunctionBody ms def
70- return LBox. Def
71- { dName = LBox. Named $ prettyShow defName
72- , dBody = body
73- , dArgs = 0
74- }
71+ -- otherwise, take fixpoint
72+ else do
73+
74+ let mnames = map defName mdefs
75+ let k = fromMaybe 0 $ elemIndex (defName defn) mnames
76+
77+ Just . LBox. ConstantDecl . Just . flip LBox. LFix k <$>
78+ forM mdefs \ def@ Defn {defName} -> do
79+ body <- compileFunctionBody mnames def
80+ return LBox. Def
81+ { dName = LBox. Named $ prettyShow defName
82+ , dBody = body
83+ , dArgs = 0
84+ }
0 commit comments