Skip to content

Commit 1107ae3

Browse files
committed
almost done with cleaning up
1 parent c1d3e1f commit 1107ae3

File tree

18 files changed

+356
-396
lines changed

18 files changed

+356
-396
lines changed

agda2lambox.cabal

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,12 @@ executable agda2lambox
1818
other-modules: Agda,
1919
Agda.Lib,
2020
Agda.Utils,
21-
Agda2Lambox.Monad,
22-
Agda2Lambox.Convert,
23-
Agda2Lambox.Convert.Class,
24-
Agda2Lambox.Convert.Data,
25-
Agda2Lambox.Convert.Function,
26-
Agda2Lambox.Convert.Record,
27-
Agda2Lambox.Convert.Term,
28-
Agda2Lambox,
29-
Utils,
21+
Agda2Lambox.Compile.Utils,
22+
Agda2Lambox.Compile.Term,
23+
Agda2Lambox.Compile.Function,
24+
Agda2Lambox.Compile.Data,
25+
Agda2Lambox.Compile.Record,
26+
Agda2Lambox.Compile,
3027
LambdaBox,
3128
CoqGen,
3229
Paths_agda2lambox
@@ -46,3 +43,4 @@ executable agda2lambox
4643
TypeFamilies TypeOperators TypeApplications
4744
FunctionalDependencies TypeSynonymInstances ConstraintKinds
4845
DoAndIfThenElse BlockArguments MultiWayIf
46+
ImportQualifiedPost

src/Agda/Utils.hs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
module Agda.Utils where
55

66
import Control.Monad.Error.Class ( MonadError )
7-
import Control.Monad.IO.Class ( MonadIO )
7+
import Control.Monad.IO.Class ( MonadIO(liftIO) )
88
import Control.Monad ( filterM )
99
import Control.Arrow ( first )
1010

@@ -13,7 +13,6 @@ import qualified Data.List.NonEmpty as NE ( fromList )
1313
import Data.Maybe ( isJust, isNothing )
1414
import Data.Bifunctor ( second )
1515

16-
import Utils
1716
import Agda.Lib
1817
import Agda.TypeChecking.Free.Lazy (underBinder)
1918
import Agda.TypeChecking.Datatypes (getConstructorInfo, ConstructorInfo(..))
@@ -54,7 +53,7 @@ currentCtx = fmap (first pp . unDom) <$> getContext
5453
reportCurrentCtx :: (MonadIO m, MonadTCEnv m) => m ()
5554
reportCurrentCtx = do
5655
ctx <- currentCtx
57-
report $ " currentCtx: " <> pp ctx
56+
liftIO $ putStrLn $ " currentCtx: " <> pp ctx
5857

5958
unqual :: QName -> String
6059
unqual = pp . last . qnameToList0

src/Agda2Lambox.hs

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/Agda2Lambox/Compile.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module Agda2Lambox.Compile where
Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{-# LANGUAGE NamedFieldPuns, ImportQualifiedPost #-}
22
-- | Convert Agda datatypes to λ□ inductive declarations
3-
module Agda2Lambox.Convert.Data
4-
( convertDatatype
3+
module Agda2Lambox.Compile.Data
4+
( compileData
55
) where
66

77
import Control.Monad.Reader ( ask, liftIO )
@@ -11,11 +11,7 @@ import Data.Foldable ( toList )
1111
import Data.List ( elemIndex )
1212
import Data.Maybe ( isJust, listToMaybe )
1313

14-
import Utils
15-
1614
import Agda ( liftTCM )
17-
import Agda.Lib ()
18-
import Agda.Utils
1915
import Agda.Syntax.Abstract.Name ( qnameModule, qnameName )
2016
import Agda.TypeChecking.Monad.Base
2117
import Agda.TypeChecking.Monad.Env ( withCurrentModule )
@@ -25,24 +21,24 @@ import Agda.Compiler.Backend ( getConstInfo, lookupMutualBlock )
2521
import Agda.Syntax.Treeless ( EvaluationStrategy(EagerEvaluation) )
2622
import Agda.Syntax.Common.Pretty ( prettyShow )
2723

28-
import LambdaBox
29-
30-
import Agda2Lambox.Monad
31-
import Agda2Lambox.Convert.Class
32-
import Agda.Utils.Monad (guardWithError)
24+
import Agda2Lambox.Compile.Utils
25+
import LambdaBox qualified as LBox
3326

3427

3528
-- | Toplevel conversion from a datatype definition to a Lambdabox declaration.
36-
convertDatatype :: Definition :~> Maybe GlobalDecl
37-
convertDatatype defn@Defn{defName, defMutual} = do
29+
compileData :: Definition -> TCM (Maybe LBox.GlobalDecl)
30+
compileData defn@Defn{defName, defMutual} = do
3831
let Datatype{..} = theDef defn
39-
let Just names = dataMutual
32+
let names = case dataMutual of
33+
Just [] -> [defName]
34+
Just xs -> xs
35+
Nothing -> fail "error"
4036

4137
-- we consider that the *lowest name* in the mutual block
4238
-- is the *representative* of the mutual block
4339
-- i.e that's when we trigger the compilation of the mutual block
4440

45-
if not (null names) && Just defName /= listToMaybe names then return Nothing
41+
if Just defName /= listToMaybe names then return Nothing
4642
else do
4743

4844
-- when it's time to compile the mutual block
@@ -52,10 +48,10 @@ convertDatatype defn@Defn{defName, defMutual} = do
5248

5349
unless onlyDatas $ fail "not supported: mutual datatypes with non-datatypes"
5450

55-
bodies <- forM names $ liftTCM . getConstInfo >=> actuallyConvertDatatype
51+
bodies <- forM names $ getConstInfo >=> actuallyConvertDatatype
5652

57-
return $ Just $ InductiveDecl $ MutualInductive
58-
{ indFinite = Finite
53+
return $ Just $ LBox.InductiveDecl $ LBox.MutualInductive
54+
{ indFinite = LBox.Finite
5955
-- NOTE(flupe): Agda's datatypes are *always* finite?
6056
-- Co-induction is restricted to records.
6157
-- We may want to set BiFinite for non-recursive datatypes, but I don't know yet.
@@ -66,24 +62,23 @@ convertDatatype defn@Defn{defName, defMutual} = do
6662

6763

6864

69-
actuallyConvertDatatype :: Definition :~> OneInductiveBody
70-
actuallyConvertDatatype defn@Defn{defName, theDef, defMutual} =
71-
withCurrentModule (qnameModule defName) do
65+
actuallyConvertDatatype :: Definition -> TCM LBox.OneInductiveBody
66+
actuallyConvertDatatype defn@Defn{defName, theDef, defMutual} = do
7267
let Datatype{..} = theDef
7368

74-
ctors :: [ConstructorBody]
69+
ctors :: [LBox.ConstructorBody]
7570
<- forM dataCons \cname -> do
7671
DataCon arity <- getConstructorInfo cname
77-
return Ctor
72+
return LBox.Ctor
7873
{ ctorName = prettyShow $ qnameName cname
7974
, ctorArgs = arity
8075
}
8176

82-
return OneInductive
77+
return LBox.OneInductive
8378
{ indName = prettyShow $ qnameName defName
8479
, indPropositional = False
8580
-- TODO(flupe): ^ take care of this (use datatypeSort to figure this out)
86-
, indKElim = IntoAny
81+
, indKElim = LBox.IntoAny
8782
-- TODO(flupe): also take care of this (with the Sort)
8883
, indCtors = ctors
8984
, indProjs = []
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{-# LANGUAGE NamedFieldPuns #-}
2+
-- | Convert Agda functions to λ□ constant declarations
3+
module Agda2Lambox.Compile.Function
4+
( compileFunction
5+
) where
6+
7+
import Control.Monad ( forM, when )
8+
import Data.List ( elemIndex )
9+
import Data.Maybe ( isNothing, fromMaybe )
10+
11+
import Agda.Lib ( (^.), funInline )
12+
import Agda.Syntax.Abstract.Name ( QName, qnameModule )
13+
import Agda.TypeChecking.Monad.Base
14+
import Agda.Compiler.ToTreeless ( toTreeless )
15+
import Agda.Compiler.Backend ( getConstInfo )
16+
import Agda.Syntax.Treeless ( EvaluationStrategy(EagerEvaluation) )
17+
import Agda.Syntax.Common.Pretty ( prettyShow )
18+
import Agda.Syntax.Common ( hasQuantityω )
19+
import Agda.Utils.Monad (guardWithError)
20+
21+
import Agda.Utils ( etaExpandCtor )
22+
import Agda2Lambox.Compile.Utils
23+
import Agda2Lambox.Compile.Term ( runC, compileTerm, withMutuals )
24+
import LambdaBox qualified as LBox
25+
26+
27+
-- | Check whether a definition is a function.
28+
isFunction :: Definition -> Bool
29+
isFunction Defn{..} | Function{} <- theDef = True
30+
isFunction _ = False
31+
32+
33+
-- | Convert a function body to a Lambdabox term.
34+
compileFunctionBody :: [QName] -> Definition -> TCM LBox.Term
35+
compileFunctionBody fixpoints Defn{defName} = do
36+
Just t <-toTreeless EagerEvaluation defName
37+
runC . withMutuals fixpoints . compileTerm =<< etaExpandCtor t
38+
39+
40+
-- | Whether to compile a function definition to λ□.
41+
shouldCompileFunction :: Definition -> Bool
42+
shouldCompileFunction def@Defn{theDef} | Function{..} <- theDef
43+
= not (theDef ^. funInline) -- not inlined (from module application)
44+
&& isNothing funExtLam -- not a pattern-lambda-generated function NOTE(flupe): ?
45+
&& isNothing funWith -- not a with-generated function NOTE(flupe): ?
46+
&& hasQuantityω def -- non-erased
47+
48+
49+
-- | Convert a function definition to a λ□ declaration.
50+
compileFunction :: Definition -> TCM (Maybe LBox.GlobalDecl)
51+
compileFunction defn | not (shouldCompileFunction defn) = return Nothing
52+
compileFunction defn@Defn{defName, theDef} = do
53+
let Function{funMutual = Just ms} = theDef
54+
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
58+
59+
-- otherwise, take fixpoint
60+
else do
61+
mdefs :: [Definition] <- mapM getConstInfo ms
62+
63+
when (any (not . isFunction) mdefs) $ fail "only mutually defined functions are supported."
64+
65+
let k = fromMaybe 0 $ elemIndex defName ms
66+
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+
}

src/Agda2Lambox/Compile/Record.hs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{-# LANGUAGE NamedFieldPuns #-}
2+
-- | Convert Agda records to λ□ inductive declarations
3+
module Agda2Lambox.Compile.Record
4+
( compileRecord
5+
) where
6+
7+
import Control.Monad ( forM )
8+
import Control.Monad.Reader ( ask, liftIO )
9+
import Data.List ( elemIndex )
10+
import Data.Maybe ( maybe )
11+
12+
import Agda.Syntax.Abstract.Name ( qnameModule, qnameName )
13+
import Agda.TypeChecking.Monad.Base
14+
import Agda.TypeChecking.Datatypes ( ConstructorInfo(..), getConstructorInfo )
15+
import Agda.Syntax.Internal ( ConHead(..), unDom )
16+
import Agda.Syntax.Common.Pretty ( prettyShow )
17+
import Agda.Syntax.Common ( Induction(..) )
18+
19+
import Agda2Lambox.Compile.Utils
20+
import LambdaBox qualified as LBox
21+
22+
inductionToRecKind :: Induction -> LBox.RecursivityKind
23+
inductionToRecKind = \case
24+
Inductive -> LBox.Finite
25+
CoInductive -> LBox.CoFinite
26+
27+
-- | Convert a datatype definition to a Lambdabox declaration.
28+
compileRecord :: Definition -> TCM LBox.GlobalDecl
29+
compileRecord defn@Defn{defName, theDef} =
30+
let
31+
32+
Record{..} = theDef
33+
ConHead{conName, conFields} = recConHead
34+
35+
fields :: [LBox.ProjectionBody]
36+
= LBox.Proj . prettyShow . qnameName . unDom <$> recFields
37+
38+
record = LBox.OneInductive
39+
{ indName = prettyShow $ qnameName defName
40+
, indPropositional = False -- TODO(flupe): take care of this
41+
, indKElim = LBox.IntoAny -- TODO(flupe): also take care of this
42+
, indCtors = [ LBox.Ctor (prettyShow $ qnameName conName)
43+
(length conFields) ]
44+
, indProjs = fields
45+
}
46+
47+
in return $ LBox.InductiveDecl LBox.MutualInductive
48+
{ indFinite = maybe LBox.BiFinite inductionToRecKind recInduction
49+
, indPars = 0
50+
-- TODO(flupe):
51+
-- ^ double-check, but it doesn't look like
52+
-- this could be anything other than 0.
53+
, indBodies = [record]
54+
}

0 commit comments

Comments
 (0)