Skip to content

Commit d279046

Browse files
committed
fix error reporting
1 parent cee3006 commit d279046

File tree

5 files changed

+81
-29
lines changed

5 files changed

+81
-29
lines changed

src/Agda2Lambox/Compile/Target.hs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ module Agda2Lambox.Compile.Target
44
( Typing(..)
55
, Target(..)
66
, WhenTyped(..)
7+
, WhenUntyped(..)
78
, getTyped
9+
, getUntyped
810
, whenTyped
11+
, whenUntyped
912
) where
1013

1114
import Data.Foldable (Foldable(foldMap))
@@ -40,16 +43,45 @@ instance Foldable (WhenTyped t) where
4043
foldMap f None = mempty
4144
foldMap f (Some x) = f x
4245

46+
-- | Type wrapper that contains a value iff we're in the untyped setting.
47+
data WhenUntyped (t :: Typing) (a :: Type) :: Type where
48+
NoneU :: WhenUntyped Typed a
49+
SomeU :: a -> WhenUntyped Untyped a
4350

44-
-- | Retrieve a value when it's there for sure.
51+
instance Functor (WhenUntyped t) where
52+
fmap f NoneU = NoneU
53+
fmap f (SomeU x) = SomeU (f x)
54+
55+
instance Applicative (WhenUntyped Untyped) where
56+
pure = SomeU
57+
SomeU f <*> SomeU x = SomeU (f x)
58+
59+
instance Monad (WhenUntyped Untyped) where
60+
SomeU x >>= f = f x
61+
62+
instance Foldable (WhenUntyped t) where
63+
foldMap f NoneU = mempty
64+
foldMap f (SomeU x) = f x
65+
66+
67+
-- | Retrieve a value when it's there for sure, in the typed setting.
4568
getTyped :: WhenTyped Typed a -> a
4669
getTyped (Some x) = x
4770

71+
-- | Retrieve a value when it's there for sure, in the untyped setting.
72+
getUntyped :: WhenUntyped Untyped a -> a
73+
getUntyped (SomeU x) = x
74+
4875
-- | Only perform a computation when targetting typed.
4976
whenTyped :: Applicative m => Target t -> m a -> m (WhenTyped t a)
5077
whenTyped ToUntyped _ = pure None
5178
whenTyped ToTyped x = Some <$> x
5279

80+
-- | Only perform a computation when targetting untyped.
81+
whenUntyped :: Applicative m => Target t -> m a -> m (WhenUntyped t a)
82+
whenUntyped ToTyped _ = pure NoneU
83+
whenUntyped ToUntyped x = SomeU <$> x
84+
5385
instance NFData (Target t) where
5486
rnf ToTyped = ()
5587
rnf ToUntyped = ()

src/CoqGen.hs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module CoqGen (prettyCoq) where
44

55
import Data.Bifunctor(bimap)
66
import Data.List(intercalate)
7+
import Data.List.NonEmpty qualified as NEL
78

89
import Agda.Syntax.Common.Pretty
910
import LambdaBox
@@ -189,8 +190,8 @@ instance ToCoq t (GlobalEnv t) where
189190
pcoq ToUntyped (GlobalEnv env) = upcoq env
190191
pcoq ToTyped (GlobalEnv env) = tpcoq $ flip map env \(kn, decl) -> ((kn, True), decl)
191192

192-
instance ToCoq t (CoqModule t) where
193-
pcoq ToUntyped CoqModule{..} = vsep
193+
instance ToCoq t (LBoxModule t) where
194+
pcoq ToUntyped LBoxModule{..} = vsep
194195
[ vcat
195196
[ "From Coq Require Import List."
196197
, "From MetaCoq.Common Require Import BasicAst Kernames Universes."
@@ -201,11 +202,11 @@ instance ToCoq t (CoqModule t) where
201202
]
202203

203204
, hang "Definition env : global_declarations :=" 2 $
204-
upcoq coqEnv <> "."
205+
upcoq lboxEnv <> "."
205206

206207
, "Compute @check_wf_glob eflags env."
207208

208-
, vsep $ flip map (zip [1..] $ reverse coqPrograms) \(i :: Int, kn) ->
209+
, vsep $ flip map (zip [1..] $ reverse $ NEL.toList $ getUntyped lboxMain) \(i :: Int, kn) ->
209210
let progname = "prog" <> pretty i in vsep
210211
[ hang ("Definition " <> progname <> " : program :=") 2 $
211212
upcoq (text "env" :: Doc, LConst kn)
@@ -214,7 +215,7 @@ instance ToCoq t (CoqModule t) where
214215
]
215216
]
216217

217-
pcoq ToTyped CoqModule{..} = vsep
218+
pcoq ToTyped LBoxModule{..} = vsep
218219
[ vcat
219220
[ "From Coq Require Import List."
220221
, "From MetaCoq.Common Require Import BasicAst Kernames Universes."
@@ -224,5 +225,5 @@ instance ToCoq t (CoqModule t) where
224225
, "Import ListNotations."
225226
]
226227

227-
, hang "Definition env : global_env :=" 2 $ tpcoq coqEnv <> "."
228+
, hang "Definition env : global_env :=" 2 $ tpcoq lboxEnv <> "."
228229
]

src/LambdaBox/Env.hs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module LambdaBox.Env where
1818

1919

2020
import Data.Kind ( Type )
21+
import Data.List.NonEmpty ( NonEmpty )
2122

2223
import Agda.Syntax.Common.Pretty
2324

@@ -121,9 +122,9 @@ data GlobalDecl (t :: Typing) :: Type where
121122
newtype GlobalEnv t = GlobalEnv [(KerName, GlobalDecl t)]
122123

123124
-- | Generated module
124-
data CoqModule t = CoqModule
125-
{ coqEnv :: GlobalEnv t
126-
, coqPrograms :: [KerName]
125+
data LBoxModule t = LBoxModule
126+
{ lboxEnv :: GlobalEnv t
127+
, lboxMain :: WhenUntyped t (NonEmpty KerName)
127128
}
128129

129130

@@ -171,5 +172,8 @@ instance Pretty (GlobalEnv t) where
171172
vsep $ flip map (reverse env) \(kn, d) ->
172173
hang (pretty kn <> ":") 2 (pretty d)
173174

174-
instance Pretty (CoqModule t) where
175-
pretty CoqModule{..} = pretty coqEnv
175+
instance Pretty (LBoxModule t) where
176+
pretty LBoxModule{..} = vcat
177+
[ pretty lboxEnv
178+
, flip foldMap lboxMain \kn -> "main program:" <+> pretty kn
179+
]

src/Main.hs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ import Control.Monad ( unless, filterM )
77
import Control.Monad.IO.Class ( liftIO )
88
import Control.DeepSeq ( NFData(rnf) )
99
import Data.Function ( (&) )
10+
import Data.List.NonEmpty ( NonEmpty )
11+
import Data.List.NonEmpty qualified as NEL
1012
import Data.Maybe ( fromMaybe )
1113
import Data.Version ( showVersion )
1214
import Data.Text ( pack )
1315
import GHC.Generics ( Generic )
1416
import System.Console.GetOpt ( OptDescr(Option), ArgDescr(..) )
1517
import System.Directory ( createDirectoryIfMissing )
16-
import System.FilePath ( (</>) )
18+
import System.FilePath ( (</>), (-<.>) )
1719
import Data.Text.Lazy.IO qualified as LText
1820

1921
import Paths_agda2lambox ( version )
@@ -32,6 +34,7 @@ import Agda2Lambox.Compile (compile)
3234
import CoqGen ( prettyCoq )
3335
import SExpr ( prettySexp )
3436
import LambdaBox.Env
37+
import LambdaBox.Names (KerName)
3538
import Agda2Lambox.Compile.Monad (runCompile, CompileEnv(..))
3639

3740

@@ -124,25 +127,37 @@ writeModule
124127
writeModule opts menv NotMain _ _ = pure ()
125128
writeModule Options{..} menv IsMain m defs = do
126129
outDir <- flip fromMaybe optOutDir <$> compileDir
127-
env <- runCompile (CompileEnv optNoBlocks) $ compile optTarget defs
128130
programs <- filterM hasPragma defs
129131

132+
-- get defs annotated with a COMPILE pragma
133+
-- throw an error if none, when targetting untyped lbox
134+
mains <- getMain optTarget programs
135+
env <- runCompile (CompileEnv optNoBlocks) $ compile optTarget defs
136+
130137
liftIO $ createDirectoryIfMissing True outDir
131138

132-
let fileName = (outDir </>) . moduleNameToFileName m
133-
coqMod = CoqModule env (map qnameToKName programs)
139+
let fileName = outDir </> prettyShow m
140+
let lboxMod = LBoxModule env mains
134141

135142
liftIO do
136-
putStrLn $ "Writing " <> fileName ".txt"
137-
pp coqMod <> "\n" & writeFile (fileName ".txt")
143+
putStrLn $ "Writing " <> fileName -<.> ".txt"
144+
pp lboxMod <> "\n" & writeFile (fileName -<.> ".txt")
138145

139146
liftIO $ case optOutput of
140147
RocqOutput -> do
141-
putStrLn $ "Writing " <> fileName ".v"
142-
prettyCoq optTarget coqMod <> "\n"
143-
& writeFile (fileName ".v")
148+
putStrLn $ "Writing " <> fileName -<.> ".v"
149+
prettyCoq optTarget lboxMod <> "\n"
150+
& writeFile (fileName -<.> ".v")
144151

145152
AstOutput -> do
146-
putStrLn $ "Writing " <> fileName ".ast"
147-
prettySexp optTarget coqMod <> "\n"
148-
& LText.writeFile (fileName ".ast")
153+
putStrLn $ "Writing " <> fileName -<.> ".ast"
154+
prettySexp optTarget lboxMod <> "\n"
155+
& LText.writeFile (fileName -<.> ".ast")
156+
157+
where
158+
getMain :: Target t -> [QName] -> TCM (WhenUntyped t (NonEmpty KerName))
159+
getMain ToTyped _ = pure NoneU
160+
getMain ToUntyped qs =
161+
case NEL.nonEmpty qs of
162+
Nothing -> genericError "No main program specified. Please use a COMPILE pragma."
163+
Just ms -> pure $ SomeU (NEL.map qnameToKName ms)

src/SExpr.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module SExpr (ToSexp, prettySexp) where
55

66
import Data.Bifunctor(bimap)
77
import Data.List(intercalate)
8+
import Data.List.NonEmpty qualified as NEL (head)
89

910
import Agda.Syntax.Common.Pretty
1011
import LambdaBox
@@ -184,8 +185,7 @@ instance ToSexp t (GlobalEnv t) where
184185
toSexp t@ToUntyped (GlobalEnv env) = toSexp t env
185186
toSexp t@ToTyped (GlobalEnv env) = toSexp t $ flip map env \(kn, decl) -> ((kn, True), decl)
186187

187-
-- TODO(flupe): handle programs
188-
instance ToSexp t (CoqModule t) where
189-
toSexp t@ToUntyped CoqModule{..} =
190-
toSexp t (coqEnv, ctor t "tConst" [S $ head coqPrograms])
191-
toSexp t@ToTyped CoqModule{..} = toSexp t coqEnv
188+
instance ToSexp t (LBoxModule t) where
189+
toSexp t@ToUntyped LBoxModule{..} =
190+
toSexp t (lboxEnv, ctor t "tConst" [S $ NEL.head $ getUntyped lboxMain])
191+
toSexp t@ToTyped LBoxModule{..} = toSexp t lboxEnv

0 commit comments

Comments
 (0)