{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
#if __GLASGOW_HASKELL__ >= 800
{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}
#endif
module BNFC.Backend.Agda (makeAgda) where
import Prelude hiding ((<>))
import Control.Monad.State hiding (when)
import Data.Char
import Data.Function (on)
import qualified Data.List as List
import Data.List.NonEmpty (NonEmpty((:|)))
import qualified Data.List.NonEmpty as List1
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import Data.String (IsString)
import BNFC.CF
import BNFC.Backend.Base (Backend, mkfile)
import BNFC.Backend.Haskell.HsOpts
import BNFC.Backend.Haskell.Utils (parserName, catToType, mkDefName, typeToHaskell', comment)
import BNFC.Options (SharedOptions, TokenText(..), tokenText)
import BNFC.PrettyPrint
import BNFC.Utils (ModuleName, replace, when, table)
data ConstructorStyle
= UnnamedArg
| NamedArg
data ImportNumeric
= YesImportNumeric
| NoImportNumeric
deriving (ImportNumeric -> ImportNumeric -> Bool
(ImportNumeric -> ImportNumeric -> Bool)
-> (ImportNumeric -> ImportNumeric -> Bool) -> Eq ImportNumeric
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ImportNumeric -> ImportNumeric -> Bool
$c/= :: ImportNumeric -> ImportNumeric -> Bool
== :: ImportNumeric -> ImportNumeric -> Bool
$c== :: ImportNumeric -> ImportNumeric -> Bool
Eq)
makeAgda
:: String
-> SharedOptions
-> CF
-> Backend
makeAgda :: [Char] -> SharedOptions -> CF -> Backend
makeAgda [Char]
time SharedOptions
opts CF
cf = do
[Char] -> MakeComment -> Doc -> Backend
forall c. FileContent c => [Char] -> MakeComment -> c -> Backend
mkfile (SharedOptions -> [Char]
agdaASTFile SharedOptions
opts) MakeComment
comment (Doc -> Backend) -> Doc -> Backend
forall a b. (a -> b) -> a -> b
$
[Char] -> TokenText -> [Char] -> [Char] -> [Char] -> CF -> Doc
cf2AgdaAST [Char]
time (SharedOptions -> TokenText
tokenText SharedOptions
opts) (SharedOptions -> [Char]
agdaASTFileM SharedOptions
opts) (SharedOptions -> [Char]
absFileM SharedOptions
opts) (SharedOptions -> [Char]
printerFileM SharedOptions
opts) CF
cf
[Char] -> MakeComment -> Doc -> Backend
forall c. FileContent c => [Char] -> MakeComment -> c -> Backend
mkfile (SharedOptions -> [Char]
agdaParserFile SharedOptions
opts) MakeComment
comment (Doc -> Backend) -> Doc -> Backend
forall a b. (a -> b) -> a -> b
$
[Char]
-> TokenText
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> Maybe [Char]
-> [Cat]
-> Doc
cf2AgdaParser [Char]
time (SharedOptions -> TokenText
tokenText SharedOptions
opts) (SharedOptions -> [Char]
agdaParserFileM SharedOptions
opts) (SharedOptions -> [Char]
agdaASTFileM SharedOptions
opts) (SharedOptions -> [Char]
errFileM SharedOptions
opts) (SharedOptions -> [Char]
happyFileM SharedOptions
opts)
Maybe [Char]
layoutMod
[Cat]
parserCats
[Char] -> MakeComment -> Doc -> Backend
forall c. FileContent c => [Char] -> MakeComment -> c -> Backend
mkfile (SharedOptions -> [Char]
agdaLibFile SharedOptions
opts) MakeComment
comment (Doc -> Backend) -> Doc -> Backend
forall a b. (a -> b) -> a -> b
$
[Char] -> Doc
agdaLibContents (SharedOptions -> [Char]
agdaLibFileM SharedOptions
opts)
[Char] -> MakeComment -> Doc -> Backend
forall c. FileContent c => [Char] -> MakeComment -> c -> Backend
mkfile (SharedOptions -> [Char]
agdaMainFile SharedOptions
opts) MakeComment
comment (Doc -> Backend) -> Doc -> Backend
forall a b. (a -> b) -> a -> b
$
[Char] -> [Char] -> [Char] -> [Char] -> Bool -> Cat -> Doc
agdaMainContents (SharedOptions -> [Char]
agdaMainFileM SharedOptions
opts) (SharedOptions -> [Char]
agdaLibFileM SharedOptions
opts) (SharedOptions -> [Char]
agdaASTFileM SharedOptions
opts) (SharedOptions -> [Char]
agdaParserFileM SharedOptions
opts)
(CF -> Bool
hasLayout CF
cf)
(CF -> Cat
firstEntry CF
cf)
where
parserCats :: [Cat]
parserCats :: [Cat]
parserCats = NonEmpty Cat -> [Cat]
forall a. NonEmpty a -> [a]
List1.toList (NonEmpty Cat -> [Cat]) -> NonEmpty Cat -> [Cat]
forall a b. (a -> b) -> a -> b
$ CF -> NonEmpty Cat
forall f. CFG f -> NonEmpty Cat
allEntryPoints CF
cf
layoutMod :: Maybe String
layoutMod :: Maybe [Char]
layoutMod = Bool -> Maybe [Char] -> Maybe [Char]
forall m. Monoid m => Bool -> m -> m
when (CF -> Bool
hasLayout CF
cf) (Maybe [Char] -> Maybe [Char]) -> Maybe [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just (SharedOptions -> [Char]
layoutFileM SharedOptions
opts)
cf2AgdaAST
:: String
-> TokenText
-> String
-> String
-> String
-> CF
-> Doc
cf2AgdaAST :: [Char] -> TokenText -> [Char] -> [Char] -> [Char] -> CF -> Doc
cf2AgdaAST [Char]
time TokenText
tokenText [Char]
mod [Char]
amod [Char]
pmod CF
cf = [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
[ [Char] -> [Char] -> Doc
preamble [Char]
time [Char]
"abstract syntax data types"
, [Doc] -> Doc
hsep [ Doc
"module", [Char] -> Doc
text [Char]
mod, Doc
"where" ]
, ImportNumeric -> Bool -> Bool -> Doc
imports ImportNumeric
YesImportNumeric Bool
False Bool
usesPos
, Bool -> Doc -> Doc
forall m. Monoid m => Bool -> m -> m
when Bool
usesString (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
hsep [ Doc
"String", Doc
equals, Doc
forall a. IsString a => a
listT, Doc
forall a. IsString a => a
charT ]
, TokenText -> Bool -> [[Char]] -> Doc
importPragmas TokenText
tokenText Bool
usesPos
[ [[Char]] -> [Char]
unwords [ [Char]
"qualified", [Char]
amod ]
, [[Char]] -> [Char]
unwords [ [Char]
pmod, [Char]
"(printTree)" ]
]
, Bool -> Doc -> Doc
forall m. Monoid m => Bool -> m -> m
when Bool
usesPos Doc
defineIntAndPair
, [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (([Char], Bool) -> Doc) -> [([Char], Bool)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (([Char] -> Bool -> Doc) -> ([Char], Bool) -> Doc
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (([Char] -> Bool -> Doc) -> ([Char], Bool) -> Doc)
-> ([Char] -> Bool -> Doc) -> ([Char], Bool) -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> TokenText -> [Char] -> Bool -> Doc
prToken [Char]
amod TokenText
tokenText) [([Char], Bool)]
tcats
, [Char] -> ConstructorStyle -> [Data] -> Doc
absyn [Char]
amod ConstructorStyle
NamedArg [Data]
dats
, CF -> Doc
definedRules CF
cf
, [Char] -> [Cat] -> Doc
printers [Char]
amod [Cat]
printerCats
, Doc
empty
]
where
dats :: [Data]
dats :: [Data]
dats = CF -> [Data]
cf2data CF
cf
tcats :: [(TokenCat, Bool)]
tcats :: [([Char], Bool)]
tcats = (if CF -> Bool
forall f. CFG f -> Bool
hasIdent CF
cf then (([Char]
catIdent, Bool
False) ([Char], Bool) -> [([Char], Bool)] -> [([Char], Bool)]
forall a. a -> [a] -> [a]
:) else [([Char], Bool)] -> [([Char], Bool)]
forall a. a -> a
id)
[ (WithPosition [Char] -> [Char]
forall a. WithPosition a -> a
wpThing WithPosition [Char]
name, Bool
b) | TokenReg WithPosition [Char]
name Bool
b Reg
_ <- CF -> [Pragma]
forall function. CFG function -> [Pragma]
cfgPragmas CF
cf ]
printerCats :: [Cat]
printerCats :: [Cat]
printerCats = [[Cat]] -> [Cat]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ (Data -> Cat) -> [Data] -> [Cat]
forall a b. (a -> b) -> [a] -> [b]
map Data -> Cat
forall a b. (a, b) -> a
fst (CF -> [Data]
getAbstractSyntax CF
cf)
, ([Char] -> Cat) -> [[Char]] -> [Cat]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Cat
TokenCat ([[Char]] -> [Cat]) -> [[Char]] -> [Cat]
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [[Char]]
forall a. Eq a => [a] -> [a]
List.nub ([[Char]] -> [[Char]]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ CF -> [[Char]]
forall function. CFG function -> [[Char]]
cfgLiterals CF
cf [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ (([Char], Bool) -> [Char]) -> [([Char], Bool)] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], Bool) -> [Char]
forall a b. (a, b) -> a
fst [([Char], Bool)]
tcats
]
usesString :: Bool
usesString = [Char]
"String" [Char] -> [[Char]] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` CF -> [[Char]]
forall function. CFG function -> [[Char]]
cfgLiterals CF
cf
usesPos :: Bool
usesPos = CF -> Bool
forall f. CFG f -> Bool
hasPositionTokens CF
cf
defineIntAndPair :: Doc
defineIntAndPair = [Doc] -> Doc
vsep
[ [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ Doc
"postulate" ]
, ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Doc -> Doc
nest Int
2 (Doc -> Doc) -> ([Char] -> Doc) -> [Char] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Doc
text) ([[Char]] -> [Doc]) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> a -> b
$ [Char] -> [[[Char]]] -> [[Char]]
table [Char]
" "
[ [ [Char]
forall a. IsString a => a
intT, [Char]
":", [Char]
"Set" ]
, [ [Char]
forall a. IsString a => a
intToNatT, [Char]
":", [Char]
forall a. IsString a => a
intT, [Char]
forall a. IsString a => a
arrow , [Char]
forall a. IsString a => a
natT ]
, [ [Char]
forall a. IsString a => a
natToIntT, [Char]
":", [Char]
forall a. IsString a => a
natT, [Char]
forall a. IsString a => a
arrow , [Char]
forall a. IsString a => a
intT ]
]
]
, [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\ [Char]
s -> [Doc] -> Doc
hsep [ Doc
"{-#", Doc
"COMPILE", Doc
"GHC", [Char] -> Doc
text [Char]
s, Doc
"#-}" ]) ([[Char]] -> [Doc]) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> a -> b
$
[Char] -> [[[Char]]] -> [[Char]]
table [Char]
" = "
[ [ [Char]
forall a. IsString a => a
intT, [Char]
"type Prelude.Int" ]
, [ [Char]
forall a. IsString a => a
intToNatT, [Char]
"Prelude.toInteger" ]
, [ [Char]
forall a. IsString a => a
natToIntT, [Char]
"Prelude.fromInteger" ]
]
, [Doc] -> Doc
vcat
[ Doc
"data #Pair (A B : Set) : Set where"
, Int -> Doc -> Doc
nest Int
2 (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc
"#pair : A → B → #Pair A B"
]
, Doc
"{-# COMPILE GHC #Pair = data (,) ((,)) #-}"
]
cf2AgdaParser
:: String
-> TokenText
-> String
-> String
-> String
-> String
-> Maybe String
-> [Cat]
-> Doc
cf2AgdaParser :: [Char]
-> TokenText
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> Maybe [Char]
-> [Cat]
-> Doc
cf2AgdaParser [Char]
time TokenText
tokenText [Char]
mod [Char]
astmod [Char]
emod [Char]
pmod Maybe [Char]
layoutMod [Cat]
cats = [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
[ [Char] -> [Char] -> Doc
preamble [Char]
time [Char]
"parsers"
, [Doc] -> Doc
hsep [ Doc
"module", [Char] -> Doc
text [Char]
mod, Doc
"where" ]
, ImportNumeric -> Bool -> Bool -> Doc
imports ImportNumeric
NoImportNumeric (Maybe [Char] -> Bool
forall a. Maybe a -> Bool
isJust Maybe [Char]
layoutMod) Bool
False
, [Char] -> [[Char]] -> Doc
importCats [Char]
astmod ([[Char]] -> [[Char]]
forall a. Eq a => [a] -> [a]
List.nub [[Char]]
cs)
, TokenText -> Bool -> [[Char]] -> Doc
importPragmas TokenText
tokenText Bool
False ([[Char]] -> Doc) -> [[Char]] -> Doc
forall a b. (a -> b) -> a -> b
$ [ MakeComment
qual [Char]
emod, [Char]
pmod] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [[Char]]
forall a. Maybe a -> [a]
maybeToList (MakeComment
qual MakeComment -> Maybe [Char] -> Maybe [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [Char]
layoutMod)
, Doc
"-- Error monad of BNFC"
, [Char] -> Doc
prErrM [Char]
emod
, Doc
"-- Happy parsers"
, TokenText -> Maybe [Char] -> [Cat] -> Doc
parsers TokenText
tokenText Maybe [Char]
layoutMod [Cat]
cats
, Doc
empty
]
where
cs :: [String]
cs :: [[Char]]
cs = (Cat -> Maybe [Char]) -> [Cat] -> [[Char]]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Cat -> Maybe [Char]
baseCat [Cat]
cats
baseCat :: Cat -> Maybe String
baseCat :: Cat -> Maybe [Char]
baseCat = \case
Cat [Char]
s -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
s
CoercCat [Char]
s Integer
_ -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
s
TokenCat [Char]
"Char" -> Maybe [Char]
forall a. Maybe a
Nothing
TokenCat [Char]
s -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
s
ListCat Cat
c -> Cat -> Maybe [Char]
baseCat Cat
c
qual :: MakeComment
qual [Char]
m = [Char]
"qualified " [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ [Char]
m
arrow, charT, integerT, listT, intT, natT, intToNatT, natToIntT, stringT, stringFromListT :: IsString a => a
arrow :: forall a. IsString a => a
arrow = a
"→"
charT :: forall a. IsString a => a
charT = a
"Char"
integerT :: forall a. IsString a => a
integerT = a
"Integer"
doubleT :: Doc
doubleT = Doc
"Double"
boolT :: Doc
boolT = Doc
"#Bool"
listT :: forall a. IsString a => a
listT = a
"#List"
intT :: forall a. IsString a => a
intT = a
"#Int"
natT :: forall a. IsString a => a
natT = a
"#Nat"
intToNatT :: forall a. IsString a => a
intToNatT = a
"#intToNat"
natToIntT :: forall a. IsString a => a
natToIntT = a
"#natToInt"
stringT :: forall a. IsString a => a
stringT = a
"#String"
stringFromListT :: forall a. IsString a => a
stringFromListT = a
"#stringFromList"
preamble
:: String
-> String
-> Doc
preamble :: [Char] -> [Char] -> Doc
preamble [Char]
_time [Char]
what = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
[ [Doc] -> Doc
hcat [ Doc
"-- Agda bindings for the Haskell ", [Char] -> Doc
text [Char]
what, Doc
"." ]
]
imports
:: ImportNumeric
-> Bool
-> Bool
-> Doc
imports :: ImportNumeric -> Bool -> Bool -> Doc
imports ImportNumeric
numeric Bool
layout Bool
pos = [Doc] -> Doc
vcat ([Doc] -> Doc)
-> ([[([Char], [Doc], [([Char], Doc)])]] -> [Doc])
-> [[([Char], [Doc], [([Char], Doc)])]]
-> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([Char], [Doc], [([Char], Doc)]) -> Doc)
-> [([Char], [Doc], [([Char], Doc)])] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ([Char], [Doc], [([Char], Doc)]) -> Doc
prettyImport ([([Char], [Doc], [([Char], Doc)])] -> [Doc])
-> ([[([Char], [Doc], [([Char], Doc)])]]
-> [([Char], [Doc], [([Char], Doc)])])
-> [[([Char], [Doc], [([Char], Doc)])]]
-> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[([Char], [Doc], [([Char], Doc)])]]
-> [([Char], [Doc], [([Char], Doc)])]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[([Char], [Doc], [([Char], Doc)])]] -> Doc)
-> [[([Char], [Doc], [([Char], Doc)])]] -> Doc
forall a b. (a -> b) -> a -> b
$
[ Bool
-> [([Char], [Doc], [([Char], Doc)])]
-> [([Char], [Doc], [([Char], Doc)])]
forall m. Monoid m => Bool -> m -> m
when Bool
layout
[ ([Char]
"Agda.Builtin.Bool", [], [([Char]
"Bool", Doc
boolT)]) ]
, [ ([Char]
"Agda.Builtin.Char", [Doc
forall a. IsString a => a
charT], [] ) ]
, Bool
-> [([Char], [Doc], [([Char], Doc)])]
-> [([Char], [Doc], [([Char], Doc)])]
forall m. Monoid m => Bool -> m -> m
when (ImportNumeric
numeric ImportNumeric -> ImportNumeric -> Bool
forall a. Eq a => a -> a -> Bool
== ImportNumeric
YesImportNumeric) [([Char], [Doc], [([Char], Doc)])]
importNumeric
, [ ([Char]
"Agda.Builtin.List", [Doc
"[]", Doc
"_∷_"], [([Char]
"List", Doc
forall a. IsString a => a
listT)]) ]
, Bool
-> [([Char], [Doc], [([Char], Doc)])]
-> [([Char], [Doc], [([Char], Doc)])]
forall m. Monoid m => Bool -> m -> m
when Bool
pos
[ ([Char]
"Agda.Builtin.Nat", [], [([Char]
"Nat" , Doc
forall a. IsString a => a
natT )]) ]
, [ ([Char]
"Agda.Builtin.String", [], [([Char]
"String", Doc
forall a. IsString a => a
stringT), ([Char]
"primStringFromList", Doc
forall a. IsString a => a
stringFromListT) ]) ]
]
where
importNumeric :: [(String, [Doc], [(String, Doc)])]
importNumeric :: [([Char], [Doc], [([Char], Doc)])]
importNumeric =
[ ([Char]
"Agda.Builtin.Float public", [], [([Char]
"Float", Doc
doubleT)])
, ([Char]
"Agda.Builtin.Int public", [], [([Char]
"Int", Doc
forall a. IsString a => a
integerT)])
, ([Char]
"Agda.Builtin.Int" , [], [([Char]
"pos", Doc
"#pos")])
]
prettyImport :: (String, [Doc], [(String, Doc)]) -> Doc
prettyImport :: ([Char], [Doc], [([Char], Doc)]) -> Doc
prettyImport ([Char]
m, [Doc]
use, [([Char], Doc)]
ren)
| [([Char], Doc)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([Char], Doc)]
ren = Doc
pre
| Bool
otherwise = Int -> Doc -> Doc -> Doc -> Doc -> [Doc] -> Doc
prettyList Int
2 Doc
pre Doc
lparen Doc
rparen Doc
semi ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
(([Char], Doc) -> Doc) -> [([Char], Doc)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\ ([Char]
x, Doc
d) -> [Doc] -> Doc
hsep [[Char] -> Doc
text [Char]
x, Doc
"to", Doc
d ]) [([Char], Doc)]
ren
where
pre :: Doc
pre = [Doc] -> Doc
hsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ Doc
"open", Doc
"import", [Char] -> Doc
text [Char]
m ]
, [ Doc
"using", Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
hcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
punctuate Doc
"; " [Doc]
use ]
, [ Doc
"renaming" | Bool -> Bool
not ([([Char], Doc)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [([Char], Doc)]
ren) ]
]
importCats
:: String
-> [String]
-> Doc
importCats :: [Char] -> [[Char]] -> Doc
importCats [Char]
m [[Char]]
cs = Int -> Doc -> Doc -> Doc -> Doc -> [Doc] -> Doc
prettyList Int
2 Doc
pre Doc
lparen Doc
rparen Doc
semi ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Doc
text [[Char]]
cs
where
pre :: Doc
pre = [Doc] -> Doc
hsep [ Doc
"open", Doc
"import", [Char] -> Doc
text [Char]
m, Doc
"using" ]
importPragmas
:: TokenText
-> Bool
-> [String]
-> Doc
importPragmas :: TokenText -> Bool -> [[Char]] -> Doc
importPragmas TokenText
tokenText Bool
pos [[Char]]
mods = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Doc
imp ([[Char]] -> [Doc]) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> a -> b
$ [[Char]]
base [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]]
mods
where
imp :: [Char] -> Doc
imp [Char]
s = [Doc] -> Doc
hsep [ Doc
"{-#", Doc
"FOREIGN", Doc
"GHC", Doc
"import", [Char] -> Doc
text [Char]
s, Doc
"#-}" ]
base :: [[Char]]
base = [[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ [Char]
"Prelude (" [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ [Char]
preludeImports [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ [Char]
")" ]
, Bool -> [[Char]] -> [[Char]]
forall m. Monoid m => Bool -> m -> m
when Bool
pos
[ [Char]
"qualified Prelude" ]
, case TokenText
tokenText of
TokenText
TextToken -> []
TokenText
StringToken -> []
TokenText
ByteStringToken -> [ [Char]
"qualified Data.ByteString.Char8 as BS" ]
, [ [Char]
"qualified Data.Text" ]
]
preludeImports :: [Char]
preludeImports = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
List.intercalate [Char]
", " ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [[[Char]]] -> [[Char]]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ [Char]
"Bool", [Char]
"Char", [Char]
"Double", [Char]
"Integer", [Char]
"String", [Char]
"(.)" ]
, Bool -> [[Char]] -> [[Char]]
forall m. Monoid m => Bool -> m -> m
when Bool
pos
[ [Char]
"error" ]
]
prToken :: ModuleName -> TokenText -> String -> Bool -> Doc
prToken :: [Char] -> TokenText -> [Char] -> Bool -> Doc
prToken [Char]
amod TokenText
tokenText [Char]
t Bool
pos = [Doc] -> Doc
vsep
[ if Bool
pos then [Doc] -> Doc
vcat
[ [Doc] -> Doc
hsep [ Doc
"data", [Char] -> Doc
text [Char]
t, Doc
":", Doc
"Set", Doc
"where" ]
, Int -> Doc -> Doc
nest Int
2 (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [Doc] -> Doc
hsep
[ [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ MakeComment
agdaLower [Char]
t
, Doc
":"
, Doc
"#Pair (#Pair #Int #Int)"
, Cat -> Doc
prettyCat Cat
typ
, Doc
forall a. IsString a => a
arrow, [Char] -> Doc
text [Char]
t
]
]
else ConstructorStyle -> [Char] -> [([Char], [Cat])] -> Doc
prettyData ConstructorStyle
UnnamedArg [Char]
t [(MakeComment
agdaLower [Char]
t, [ Cat
typ ])]
, [Char] -> [Char] -> [([Char], [Cat])] -> Doc
pragmaData [Char]
amod [Char]
t [([Char]
t, [])]
]
where
typ :: Cat
typ = case TokenText
tokenText of
TokenText
TextToken -> [Char] -> Cat
Cat [Char]
"#String"
TokenText
ByteStringToken -> [Char] -> Cat
Cat [Char]
"#String"
TokenText
StringToken -> Cat -> Cat
ListCat ([Char] -> Cat
Cat [Char]
"Char")
absyn :: ModuleName -> ConstructorStyle -> [Data] -> Doc
absyn :: [Char] -> ConstructorStyle -> [Data] -> Doc
absyn [Char]
_amod ConstructorStyle
_style [] = Doc
empty
absyn [Char]
amod ConstructorStyle
style [Data]
ds = [Doc] -> Doc
vsep ([Doc] -> Doc) -> ([Data] -> [Doc]) -> [Data] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc
"mutual" Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
:) ([Doc] -> [Doc]) -> ([Data] -> [Doc]) -> [Data] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Data -> [Doc]) -> [Data] -> [Doc]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Doc -> Doc) -> [Doc] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Doc -> Doc
nest Int
2) ([Doc] -> [Doc]) -> (Data -> [Doc]) -> Data -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> ConstructorStyle -> Data -> [Doc]
prData [Char]
amod ConstructorStyle
style) ([Data] -> Doc) -> [Data] -> Doc
forall a b. (a -> b) -> a -> b
$ [Data]
ds
prData :: ModuleName -> ConstructorStyle -> Data -> [Doc]
prData :: [Char] -> ConstructorStyle -> Data -> [Doc]
prData [Char]
amod ConstructorStyle
style (Cat [Char]
d, [([Char], [Cat])]
cs) = [Char] -> ConstructorStyle -> [Char] -> [([Char], [Cat])] -> [Doc]
prData' [Char]
amod ConstructorStyle
style [Char]
d [([Char], [Cat])]
cs
prData [Char]
_ ConstructorStyle
_ (Cat
c , [([Char], [Cat])]
_ ) = [Char] -> [Doc]
forall a. HasCallStack => [Char] -> a
error ([Char] -> [Doc]) -> [Char] -> [Doc]
forall a b. (a -> b) -> a -> b
$ [Char]
"prData: unexpected category " [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow Cat
c
prData' :: ModuleName -> ConstructorStyle -> String -> [(Fun, [Cat])] -> [Doc]
prData' :: [Char] -> ConstructorStyle -> [Char] -> [([Char], [Cat])] -> [Doc]
prData' [Char]
amod ConstructorStyle
style [Char]
d [([Char], [Cat])]
cs = [ ConstructorStyle -> [Char] -> [([Char], [Cat])] -> Doc
prettyData ConstructorStyle
style [Char]
d [([Char], [Cat])]
cs , [Char] -> [Char] -> [([Char], [Cat])] -> Doc
pragmaData [Char]
amod ([[Char]] -> [Char]
forall a. [a] -> a
head ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]]
words [Char]
d) [([Char], [Cat])]
cs ]
prErrM :: ModuleName -> Doc
prErrM :: [Char] -> Doc
prErrM [Char]
emod = [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ [Char] -> ConstructorStyle -> [Char] -> [([Char], [Cat])] -> [Doc]
prData' [Char]
emod ConstructorStyle
UnnamedArg [Char]
"Err A"
[ ([Char]
"Ok" , [[Char] -> Cat
Cat [Char]
"A"])
, ([Char]
"Bad", [Cat -> Cat
ListCat (Cat -> Cat) -> Cat -> Cat
forall a b. (a -> b) -> a -> b
$ [Char] -> Cat
Cat [Char]
"Char"])
]
prettyData :: ConstructorStyle -> String -> [(Fun, [Cat])] -> Doc
prettyData :: ConstructorStyle -> [Char] -> [([Char], [Cat])] -> Doc
prettyData ConstructorStyle
style [Char]
d [([Char], [Cat])]
cs = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ [Doc] -> Doc
hsep [ Doc
"data", [Char] -> Doc
text [Char]
d, Doc
colon, Doc
"Set", Doc
"where" ] ]
, [(Doc, Doc)] -> [Doc]
mkTSTable ([(Doc, Doc)] -> [Doc]) -> [(Doc, Doc)] -> [Doc]
forall a b. (a -> b) -> a -> b
$ (([Char], [Cat]) -> (Doc, Doc))
-> [([Char], [Cat])] -> [(Doc, Doc)]
forall a b. (a -> b) -> [a] -> [b]
map (ConstructorStyle -> [Char] -> ([Char], [Cat]) -> (Doc, Doc)
prettyConstructor ConstructorStyle
style [Char]
d) [([Char], [Cat])]
cs
]
where
mkTSTable :: [(Doc,Doc)] -> [Doc]
mkTSTable :: [(Doc, Doc)] -> [Doc]
mkTSTable = ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Doc -> Doc
nest Int
2 (Doc -> Doc) -> ([Char] -> Doc) -> [Char] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Doc
text) ([[Char]] -> [Doc])
-> ([(Doc, Doc)] -> [[Char]]) -> [(Doc, Doc)] -> [Doc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [[[Char]]] -> [[Char]]
table [Char]
" : " ([[[Char]]] -> [[Char]])
-> ([(Doc, Doc)] -> [[[Char]]]) -> [(Doc, Doc)] -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Doc, Doc) -> [[Char]]) -> [(Doc, Doc)] -> [[[Char]]]
forall a b. (a -> b) -> [a] -> [b]
map (Doc, Doc) -> [[Char]]
mkRow
where
mkRow :: (Doc, Doc) -> [[Char]]
mkRow (Doc
c,Doc
t) = [ Doc -> [Char]
render Doc
c, Doc -> [Char]
render Doc
t ]
pragmaData :: ModuleName -> String -> [(Fun, [Cat])] -> Doc
pragmaData :: [Char] -> [Char] -> [([Char], [Cat])] -> Doc
pragmaData [Char]
amod [Char]
d [([Char], [Cat])]
cs = Int -> Doc -> Doc -> Doc -> Doc -> [Doc] -> Doc
prettyList Int
2 Doc
pre Doc
lparen (Doc
rparen Doc -> Doc -> Doc
<+> Doc
"#-}") Doc
"|" ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
(([Char], [Cat]) -> Doc) -> [([Char], [Cat])] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> [Char] -> Doc
prettyFun [Char]
amod ([Char] -> Doc)
-> (([Char], [Cat]) -> [Char]) -> ([Char], [Cat]) -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], [Cat]) -> [Char]
forall a b. (a, b) -> a
fst) [([Char], [Cat])]
cs
where
pre :: Doc
pre = [Doc] -> Doc
hsep [ Doc
"{-#", Doc
"COMPILE", Doc
"GHC", [Char] -> Doc
text [Char]
d, Doc
equals, Doc
"data", [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Char]
amod, [Char]
".", [Char]
d ] ]
prettyConstructor :: ConstructorStyle -> String -> (Fun,[Cat]) -> (Doc,Doc)
prettyConstructor :: ConstructorStyle -> [Char] -> ([Char], [Cat]) -> (Doc, Doc)
prettyConstructor ConstructorStyle
style [Char]
d ([Char]
c, [Cat]
as) = ([Char] -> Doc
prettyCon [Char]
c,) (Doc -> (Doc, Doc)) -> Doc -> (Doc, Doc)
forall a b. (a -> b) -> a -> b
$ if [Cat] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Cat]
as then [Char] -> Doc
text [Char]
d else [Doc] -> Doc
hsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
[ ConstructorStyle -> [Cat] -> Doc
prettyConstructorArgs ConstructorStyle
style [Cat]
as
, Doc
forall a. IsString a => a
arrow
, [Char] -> Doc
text [Char]
d
]
prettyConstructorArgs :: ConstructorStyle -> [Cat] -> Doc
prettyConstructorArgs :: ConstructorStyle -> [Cat] -> Doc
prettyConstructorArgs ConstructorStyle
style [Cat]
as =
case ConstructorStyle
style of
ConstructorStyle
UnnamedArg -> [Doc] -> Doc
hsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
List.intersperse Doc
forall a. IsString a => a
arrow [Doc]
ts
ConstructorStyle
NamedArg -> [Doc] -> Doc
hsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ ((NonEmpty Doc, Doc) -> Doc) -> [(NonEmpty Doc, Doc)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\ (Doc
x :| [Doc]
xs, Doc
t) -> Doc -> Doc
parens ([Doc] -> Doc
hsep [Doc
x, [Doc] -> Doc
hsep [Doc]
xs, Doc
colon, Doc
t])) [(NonEmpty Doc, Doc)]
tel
where
ts :: [Doc]
ts = (Cat -> Doc) -> [Cat] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> Doc
prettyCat [Cat]
as
ns :: [Doc]
ns = ((Maybe Int, [Char]) -> Doc) -> [(Maybe Int, [Char])] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> Doc
text ([Char] -> Doc)
-> ((Maybe Int, [Char]) -> [Char]) -> (Maybe Int, [Char]) -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Int, [Char]) -> [Char]
forall {a}. Show a => (Maybe a, [Char]) -> [Char]
subscript) ([(Maybe Int, [Char])] -> [Doc]) -> [(Maybe Int, [Char])] -> [Doc]
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [(Maybe Int, [Char])]
forall a. Ord a => [a] -> [(Maybe Int, a)]
numberUniquely ([[Char]] -> [(Maybe Int, [Char])])
-> [[Char]] -> [(Maybe Int, [Char])]
forall a b. (a -> b) -> a -> b
$ (Cat -> [Char]) -> [Cat] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> [Char]
nameSuggestion [Cat]
as
tel :: [(NonEmpty Doc, Doc)]
tel = ((Doc, Doc) -> [Char]) -> [(Doc, Doc)] -> [(NonEmpty Doc, Doc)]
forall c a b. Eq c => ((a, b) -> c) -> [(a, b)] -> [(List1 a, b)]
aggregateOn (Doc -> [Char]
render (Doc -> [Char]) -> ((Doc, Doc) -> Doc) -> (Doc, Doc) -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Doc, Doc) -> Doc
forall a b. (a, b) -> b
snd) ([(Doc, Doc)] -> [(NonEmpty Doc, Doc)])
-> [(Doc, Doc)] -> [(NonEmpty Doc, Doc)]
forall a b. (a -> b) -> a -> b
$ [Doc] -> [Doc] -> [(Doc, Doc)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Doc]
ns [Doc]
ts
deltaSubscript :: Int
deltaSubscript = Char -> Int
ord Char
'₀' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'0'
subscript :: (Maybe a, [Char]) -> [Char]
subscript (Maybe a
m, [Char]
s) = [Char] -> (a -> [Char]) -> Maybe a -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
s (\ a
n -> [Char]
s [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ (Char -> Char) -> MakeComment
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
chr (Int -> Char) -> (Char -> Int) -> Char -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int
deltaSubscript Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (Int -> Int) -> (Char -> Int) -> Char -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Int
ord) (a -> [Char]
forall a. Show a => a -> [Char]
show a
n)) Maybe a
m
aggregateOn :: Eq c => ((a,b) -> c) -> [(a,b)] -> [(List1 a,b)]
aggregateOn :: forall c a b. Eq c => ((a, b) -> c) -> [(a, b)] -> [(List1 a, b)]
aggregateOn (a, b) -> c
f
= (NonEmpty (a, b) -> (NonEmpty a, b))
-> [NonEmpty (a, b)] -> [(NonEmpty a, b)]
forall a b. (a -> b) -> [a] -> [b]
map (\ NonEmpty (a, b)
p -> (((a, b) -> a) -> NonEmpty (a, b) -> NonEmpty a
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
List1.map (a, b) -> a
forall a b. (a, b) -> a
fst NonEmpty (a, b)
p, (a, b) -> b
forall a b. (a, b) -> b
snd (NonEmpty (a, b) -> (a, b)
forall a. NonEmpty a -> a
List1.head NonEmpty (a, b)
p)))
([NonEmpty (a, b)] -> [(NonEmpty a, b)])
-> ([(a, b)] -> [NonEmpty (a, b)]) -> [(a, b)] -> [(NonEmpty a, b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b) -> (a, b) -> Bool) -> [(a, b)] -> [NonEmpty (a, b)]
forall (f :: * -> *) a.
Foldable f =>
(a -> a -> Bool) -> f a -> [NonEmpty a]
List1.groupBy (c -> c -> Bool
forall a. Eq a => a -> a -> Bool
(==) (c -> c -> Bool) -> ((a, b) -> c) -> (a, b) -> (a, b) -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (a, b) -> c
f)
nameSuggestion :: Cat -> String
nameSuggestion :: Cat -> [Char]
nameSuggestion = \case
ListCat Cat
c -> Cat -> [Char]
nameSuggestion Cat
c [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ [Char]
"s"
CoercCat [Char]
d Integer
_ -> MakeComment
nameFor [Char]
d
Cat [Char]
d -> MakeComment
nameFor [Char]
d
TokenCat{} -> [Char]
"x"
nameFor :: String -> String
nameFor :: MakeComment
nameFor [Char]
d = [ Char -> Char
toLower (Char -> Char) -> Char -> Char
forall a b. (a -> b) -> a -> b
$ [Char] -> Char
forall a. [a] -> a
head ([Char] -> Char) -> [Char] -> Char
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> MakeComment
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'#') [Char]
d ]
numberUniquely :: forall a. Ord a => [a] -> [(Maybe Int, a)]
numberUniquely :: forall a. Ord a => [a] -> [(Maybe Int, a)]
numberUniquely [a]
as = (a -> StateT (Frequency a) Identity (Maybe Int, a))
-> [a] -> StateT (Frequency a) Identity [(Maybe Int, a)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> StateT (Frequency a) Identity (Maybe Int, a)
step [a]
as StateT (Frequency a) Identity [(Maybe Int, a)]
-> Frequency a -> [(Maybe Int, a)]
forall s a. State s a -> s -> a
`evalState` Frequency a
forall k a. Map k a
Map.empty
where
counts :: Frequency a
counts :: Frequency a
counts = (Frequency a -> a -> Frequency a)
-> Frequency a -> [a] -> Frequency a
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ((a -> Frequency a -> Frequency a)
-> Frequency a -> a -> Frequency a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> Frequency a -> Frequency a
forall a. Ord a => a -> Frequency a -> Frequency a
incr) Frequency a
forall k a. Map k a
Map.empty [a]
as
step :: a -> State (Frequency a) (Maybe Int, a)
step :: a -> StateT (Frequency a) Identity (Maybe Int, a)
step a
a = do
let n :: Int
n = Int -> a -> Frequency a -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault ([Char] -> Int
forall a. HasCallStack => [Char] -> a
error [Char]
"numberUniquelyWith") a
a Frequency a
counts
if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then (Maybe Int, a) -> StateT (Frequency a) Identity (Maybe Int, a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int
forall a. Maybe a
Nothing, a
a) else do
(Frequency a -> Frequency a) -> StateT (Frequency a) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Frequency a -> Frequency a) -> StateT (Frequency a) Identity ())
-> (Frequency a -> Frequency a) -> StateT (Frequency a) Identity ()
forall a b. (a -> b) -> a -> b
$ a -> Frequency a -> Frequency a
forall a. Ord a => a -> Frequency a -> Frequency a
incr a
a
(,a
a) (Maybe Int -> (Maybe Int, a))
-> (Frequency a -> Maybe Int) -> Frequency a -> (Maybe Int, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Frequency a -> Maybe Int
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup a
a (Frequency a -> (Maybe Int, a))
-> StateT (Frequency a) Identity (Frequency a)
-> StateT (Frequency a) Identity (Maybe Int, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT (Frequency a) Identity (Frequency a)
forall s (m :: * -> *). MonadState s m => m s
get
type Frequency a = Map a Int
incr :: Ord a => a -> Frequency a -> Frequency a
incr :: forall a. Ord a => a -> Frequency a -> Frequency a
incr = (Maybe Int -> Maybe Int) -> a -> Map a Int -> Map a Int
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter ((Maybe Int -> Maybe Int) -> a -> Map a Int -> Map a Int)
-> (Maybe Int -> Maybe Int) -> a -> Map a Int -> Map a Int
forall a b. (a -> b) -> a -> b
$ Maybe Int -> (Int -> Maybe Int) -> Maybe Int -> Maybe Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1) (Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> (Int -> Int) -> Int -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
forall a. Enum a => a -> a
succ)
definedRules :: CF -> Doc
definedRules :: CF -> Doc
definedRules CF
cf = [Doc] -> Doc
vsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (Define -> Doc) -> [Define] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Define -> Doc
mkDef ([Define] -> [Doc]) -> [Define] -> [Doc]
forall a b. (a -> b) -> a -> b
$ CF -> [Define]
forall f. CFG f -> [Define]
definitions CF
cf
where
mkDef :: Define -> Doc
mkDef (Define WithPosition [Char]
f Telescope
args Exp' [Char]
e Base
_) = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords [ WithPosition [Char] -> [Char]
forall f. IsFun f => f -> [Char]
mkDefName WithPosition [Char]
f, [Char]
":", [Char] -> Type -> [Char]
typeToHaskell' [Char]
"→" (Type -> [Char]) -> Type -> [Char]
forall a b. (a -> b) -> a -> b
$ WithPosition Type -> Type
forall a. WithPosition a -> a
wpThing WithPosition Type
t ]
| WithPosition Type
t <- Maybe (WithPosition Type) -> [WithPosition Type]
forall a. Maybe a -> [a]
maybeToList (Maybe (WithPosition Type) -> [WithPosition Type])
-> Maybe (WithPosition Type) -> [WithPosition Type]
forall a b. (a -> b) -> a -> b
$ WithPosition [Char] -> CF -> Maybe (WithPosition Type)
forall a. IsFun a => a -> CF -> Maybe (WithPosition Type)
sigLookup WithPosition [Char]
f CF
cf
]
, [ [Doc] -> Doc
hsep ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ [Char] -> Doc
text (WithPosition [Char] -> [Char]
forall f. IsFun f => f -> [Char]
mkDefName WithPosition [Char]
f), Doc
"=", Doc
"λ" ]
, (([Char], Base) -> Doc) -> Telescope -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ([Char] -> Doc
text ([Char] -> Doc)
-> (([Char], Base) -> [Char]) -> ([Char], Base) -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MakeComment
agdaLower MakeComment
-> (([Char], Base) -> [Char]) -> ([Char], Base) -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], Base) -> [Char]
forall a b. (a, b) -> a
fst) Telescope
args
, [ Doc
"→", Exp' [Char] -> Doc
forall a. Pretty a => a -> Doc
pretty (Exp' [Char] -> Doc) -> Exp' [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ Exp' [Char] -> Exp' [Char]
sanitize Exp' [Char]
e ]
]
]
]
sanitize :: Exp' [Char] -> Exp' [Char]
sanitize = \case
App [Char]
"(:)" Type
t [Exp' [Char]]
es-> [Char] -> Type -> [Exp' [Char]] -> Exp' [Char]
forall f. f -> Type -> [Exp' f] -> Exp' f
App [Char]
"_∷_" Type
t ([Exp' [Char]] -> Exp' [Char]) -> [Exp' [Char]] -> Exp' [Char]
forall a b. (a -> b) -> a -> b
$ (Exp' [Char] -> Exp' [Char]) -> [Exp' [Char]] -> [Exp' [Char]]
forall a b. (a -> b) -> [a] -> [b]
map Exp' [Char] -> Exp' [Char]
sanitize [Exp' [Char]]
es
App [Char]
x Type
t [Exp' [Char]]
es -> [Char] -> Type -> [Exp' [Char]] -> Exp' [Char]
forall f. f -> Type -> [Exp' f] -> Exp' f
App (MakeComment
agdaLower [Char]
x) Type
t ([Exp' [Char]] -> Exp' [Char]) -> [Exp' [Char]] -> Exp' [Char]
forall a b. (a -> b) -> a -> b
$ (Exp' [Char] -> Exp' [Char]) -> [Exp' [Char]] -> [Exp' [Char]]
forall a b. (a -> b) -> [a] -> [b]
map Exp' [Char] -> Exp' [Char]
sanitize [Exp' [Char]]
es
Var [Char]
x -> [Char] -> Exp' [Char]
forall f. [Char] -> Exp' f
Var ([Char] -> Exp' [Char]) -> [Char] -> Exp' [Char]
forall a b. (a -> b) -> a -> b
$ MakeComment
agdaLower [Char]
x
e :: Exp' [Char]
e@LitInt{} -> [Char] -> Type -> [Exp' [Char]] -> Exp' [Char]
forall f. f -> Type -> [Exp' f] -> Exp' f
App [Char]
"#pos" Type
dummyType [Exp' [Char]
e]
e :: Exp' [Char]
e@LitDouble{} -> Exp' [Char]
e
e :: Exp' [Char]
e@LitChar{} -> Exp' [Char]
e
e :: Exp' [Char]
e@LitString{} -> Exp' [Char]
e
printToken :: String -> Doc
printToken :: [Char] -> Doc
printToken [Char]
t = [Doc] -> Doc
vcat
[ [Doc] -> Doc
hsep [ Doc
f, Doc
colon, [Char] -> Doc
text [Char]
t, Doc
forall a. IsString a => a
arrow, Doc
forall a. IsString a => a
stringT ]
, [Doc] -> Doc
hsep [ Doc
f, Doc
lparen Doc -> Doc -> Doc
<> Doc
c Doc -> Doc -> Doc
<+> Doc
"s" Doc -> Doc -> Doc
<> Doc
rparen, Doc
equals, Doc
forall a. IsString a => a
stringFromListT, Doc
"s" ]
]
where
f :: Doc
f = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [Char]
"print" [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ [Char]
t
c :: Doc
c = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ MakeComment
agdaLower [Char]
t
printers :: ModuleName -> [Cat] -> Doc
printers :: [Char] -> [Cat] -> Doc
printers [Char]
_amod [] = Doc
empty
printers [Char]
amod [Cat]
cats = [Doc] -> Doc
vsep
[ Doc
"-- Binding the pretty printers."
, [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ Doc
"postulate" Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
: [(Doc, Doc)] -> [Doc]
mkTSTable ((Cat -> (Doc, Doc)) -> [Cat] -> [(Doc, Doc)]
forall a b. (a -> b) -> [a] -> [b]
map (Cat -> (Doc, Doc)
prettyTySig) [Cat]
cats)
, [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$ (Cat -> Doc) -> [Cat] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> Doc
pragmaBind [Cat]
cats
]
where
prettyTySig :: Cat -> (Doc, Doc)
prettyTySig Cat
c = (Cat -> Doc
agdaPrinterName Cat
c, [Doc] -> Doc
hsep [ Cat -> Doc
prettyCat Cat
c, Doc
forall a. IsString a => a
arrow, Doc
forall a. IsString a => a
stringT ])
pragmaBind :: Cat -> Doc
pragmaBind Cat
c = [Doc] -> Doc
hsep
[ Doc
"{-#", Doc
"COMPILE", Doc
"GHC", Cat -> Doc
agdaPrinterName Cat
c, Doc
equals, Doc
"\\", Doc
y, Doc
"->"
, Doc
"Data.Text.pack", Doc -> Doc
parens (Doc
"printTree" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (Doc
y Doc -> Doc -> Doc
<+> Doc
"::" Doc -> Doc -> Doc
<+> Doc
t)), Doc
"#-}"
]
where
y :: Doc
y = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ Cat -> [Char]
nameSuggestion Cat
c
t :: Doc
t = (Doc -> Doc) -> Doc -> Cat -> Doc
catToType (([Char] -> Doc
text [Char]
amod Doc -> Doc -> Doc
<> [Char] -> Doc
text [Char]
".") Doc -> Doc -> Doc
<>) Doc
empty Cat
c
parsers
:: TokenText
-> Maybe String
-> [Cat]
-> Doc
parsers :: TokenText -> Maybe [Char] -> [Cat] -> Doc
parsers TokenText
tokenText Maybe [Char]
layoutMod [Cat]
cats =
[Doc] -> Doc
vcat (Doc
"postulate" Doc -> [Doc] -> [Doc]
forall a. a -> [a] -> [a]
: (Cat -> Doc) -> [Cat] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Doc -> Doc
nest Int
2 (Doc -> Doc) -> (Cat -> Doc) -> Cat -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cat -> Doc
prettyTySig) [Cat]
cats)
Doc -> Doc -> Doc
$++$
[Doc] -> Doc
vcat ((Cat -> Doc) -> [Cat] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Cat -> Doc
pragmaBind [Cat]
cats)
where
prettyTySig :: Cat -> Doc
prettyTySig :: Cat -> Doc
prettyTySig Cat
c = [Doc] -> Doc
hsep ([Doc] -> Doc) -> ([[Doc]] -> [Doc]) -> [[Doc]] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Doc]] -> Doc) -> [[Doc]] -> Doc
forall a b. (a -> b) -> a -> b
$
[ [ Cat -> Doc
agdaParserName Cat
c, Doc
colon ]
, Bool -> [Doc] -> [Doc]
forall m. Monoid m => Bool -> m -> m
when Bool
layout [ Doc
boolT, Doc
forall a. IsString a => a
arrow ]
, [ Doc
forall a. IsString a => a
stringT, Doc
forall a. IsString a => a
arrow, Doc
"Err", Cat -> Doc
prettyCatParens Cat
c ]
]
pragmaBind :: Cat -> Doc
pragmaBind :: Cat -> Doc
pragmaBind Cat
c = [Doc] -> Doc
hsep ([Doc] -> Doc) -> ([[Doc]] -> [Doc]) -> [[Doc]] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Doc]] -> Doc) -> [[Doc]] -> Doc
forall a b. (a -> b) -> a -> b
$
[ [ Doc
"{-#", Doc
"COMPILE", Doc
"GHC", Cat -> Doc
agdaParserName Cat
c, Doc
equals ]
, Bool -> [Doc] -> [Doc]
forall m. Monoid m => Bool -> m -> m
when Bool
layout [ Doc
"\\", Doc
"tl", Doc
"->" ]
, [ Cat -> Doc
parserName Cat
c, Doc
"." ]
, Bool -> [Doc] -> [Doc]
forall m. Monoid m => Bool -> m -> m
when Bool
layout [ [Doc] -> Doc
hcat [ [Char] -> Doc
text [Char]
lmod, Doc
".", Doc
"resolveLayout" ], Doc
"tl", Doc
"." ]
, [ Doc
"myLexer" ]
, case TokenText
tokenText of
TokenText
TextToken -> []
TokenText
StringToken -> [ Doc
".", Doc
"Data.Text.unpack" ]
TokenText
ByteStringToken -> [ Doc
".", Doc
"BS.pack", Doc
".", Doc
"Data.Text.unpack" ]
, [ Doc
"#-}" ]
]
layout :: Bool
layout :: Bool
layout = Maybe [Char] -> Bool
forall a. Maybe a -> Bool
isJust Maybe [Char]
layoutMod
lmod :: String
lmod :: [Char]
lmod = Maybe [Char] -> [Char]
forall a. HasCallStack => Maybe a -> a
fromJust Maybe [Char]
layoutMod
allTokenCats :: (TokenCat -> Doc) -> [TokenCat] -> Doc
allTokenCats :: ([Char] -> Doc) -> [[Char]] -> Doc
allTokenCats [Char] -> Doc
f = [Doc] -> Doc
vsep ([Doc] -> Doc) -> ([[Char]] -> [Doc]) -> [[Char]] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Doc) -> [[Char]] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> Doc
f
prettyFun :: ModuleName -> Fun -> Doc
prettyFun :: [Char] -> [Char] -> Doc
prettyFun [Char]
amod [Char]
c = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ [Char]
amod, [Char]
".", [Char]
c ]
prettyCon :: Fun -> Doc
prettyCon :: [Char] -> Doc
prettyCon = [Char] -> Doc
text ([Char] -> Doc) -> MakeComment -> [Char] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MakeComment
agdaLower
agdaLower :: String -> String
agdaLower :: MakeComment
agdaLower = MakeComment
avoidKeywords MakeComment -> MakeComment -> MakeComment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> MakeComment
forall {a}. (a -> a) -> [a] -> [a]
updateHead Char -> Char
toLower MakeComment -> MakeComment -> MakeComment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Char -> MakeComment
forall a. Eq a => a -> a -> [a] -> [a]
replace Char
'_' Char
'-'
where
updateHead :: (a -> a) -> [a] -> [a]
updateHead a -> a
_f [] = []
updateHead a -> a
f (a
x:[a]
xs) = a -> a
f a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs
avoidKeywords :: MakeComment
avoidKeywords [Char]
s
| [Char]
s [Char] -> Set [Char] -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set [Char]
agdaKeywords = [Char]
s [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ [Char]
"\'"
| Bool
otherwise = [Char]
s
agdaKeywords :: Set String
agdaKeywords :: Set [Char]
agdaKeywords = [[Char]] -> Set [Char]
forall a. Ord a => [a] -> Set a
Set.fromList ([[Char]] -> Set [Char]) -> [[Char]] -> Set [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]]
words [Char]
"abstract codata coinductive constructor data do eta-equality field forall hiding import in inductive infix infixl infixr instance let macro module mutual no-eta-equality open overlap pattern postulate primitive private public quote quoteContext quoteGoal quoteTerm record renaming rewrite Set syntax tactic unquote unquoteDecl unquoteDef using variable where with"
agdaParserName :: Cat -> Doc
agdaParserName :: Cat -> Doc
agdaParserName Cat
c = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [Char]
"parse" [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat Cat
c
agdaPrinterName :: Cat -> Doc
agdaPrinterName :: Cat -> Doc
agdaPrinterName Cat
c = [Char] -> Doc
text ([Char] -> Doc) -> [Char] -> Doc
forall a b. (a -> b) -> a -> b
$ [Char]
"print" [Char] -> MakeComment
forall a. [a] -> [a] -> [a]
++ Cat -> [Char]
identCat (Cat -> Cat
normCat Cat
c)
prettyCat :: Cat -> Doc
prettyCat :: Cat -> Doc
prettyCat = \case
Cat [Char]
s -> [Char] -> Doc
text [Char]
s
TokenCat [Char]
s -> [Char] -> Doc
text [Char]
s
CoercCat [Char]
s Integer
_ -> [Char] -> Doc
text [Char]
s
ListCat Cat
c -> Doc
forall a. IsString a => a
listT Doc -> Doc -> Doc
<+> Cat -> Doc
prettyCatParens Cat
c
prettyCatParens :: Cat -> Doc
prettyCatParens :: Cat -> Doc
prettyCatParens Cat
c = Bool -> Doc -> Doc
parensIf (Cat -> Bool
compositeCat Cat
c) (Cat -> Doc
prettyCat Cat
c)
compositeCat :: Cat -> Bool
compositeCat :: Cat -> Bool
compositeCat = \case
ListCat{} -> Bool
True
Cat
_ -> Bool
False
agdaLibContents
:: String
-> Doc
agdaLibContents :: [Char] -> Doc
agdaLibContents [Char]
mod = [Doc] -> Doc
vcat
[ Doc
"-- Basic I/O library."
, Doc
""
, Doc
"module" Doc -> Doc -> Doc
<+> [Char] -> Doc
text [Char]
mod Doc -> Doc -> Doc
<+> Doc
"where"
, Doc
""
, Doc
"open import Agda.Builtin.IO public using (IO)"
, Doc
"open import Agda.Builtin.List public using (List; []; _∷_)"
, Doc
"open import Agda.Builtin.String public using (String)"
, Doc
" renaming (primStringFromList to stringFromList)"
, Doc
"open import Agda.Builtin.Unit public using (⊤)"
, Doc
""
, Doc
"-- I/O monad."
, Doc
""
, Doc
"postulate"
, Doc
" return : ∀ {a} {A : Set a} → A → IO A"
, Doc
" _>>=_ : ∀ {a b} {A : Set a} {B : Set b} → IO A → (A → IO B) → IO B"
, Doc
""
, Doc
"{-# COMPILE GHC return = \\ _ _ -> return #-}"
, Doc
"{-# COMPILE GHC _>>=_ = \\ _ _ _ _ -> (>>=) #-}"
, Doc
""
, Doc
"infixl 1 _>>=_ _>>_"
, Doc
""
, Doc
"_>>_ : ∀ {b} {B : Set b} → IO ⊤ → IO B → IO B"
, Doc
"_>>_ = λ m m' → m >>= λ _ → m'"
, Doc
""
, Doc
"-- Co-bind and functoriality."
, Doc
""
, Doc
"infixr 1 _=<<_ _<$>_"
, Doc
""
, Doc
"_=<<_ : ∀ {a b} {A : Set a} {B : Set b} → (A → IO B) → IO A → IO B"
, Doc
"k =<< m = m >>= k"
, Doc
""
, Doc
"_<$>_ : ∀ {a b} {A : Set a} {B : Set b} → (A → B) → IO A → IO B"
, Doc
"f <$> m = do"
, Doc
" a ← m"
, Doc
" return (f a)"
, Doc
""
, Doc
"-- Binding basic I/O functionality."
, Doc
""
, Doc
"{-# FOREIGN GHC import qualified Data.Text #-}"
, Doc
"{-# FOREIGN GHC import qualified Data.Text.IO #-}"
, Doc
"{-# FOREIGN GHC import qualified System.Exit #-}"
, Doc
"{-# FOREIGN GHC import qualified System.Environment #-}"
, Doc
"{-# FOREIGN GHC import qualified System.IO #-}"
, Doc
""
, Doc
"postulate"
, Doc
" exitFailure : ∀{a} {A : Set a} → IO A"
, Doc
" getArgs : IO (List String)"
, Doc
" putStrLn : String → IO ⊤"
, Doc
" readFiniteFile : String → IO String"
, Doc
""
, Doc
"{-# COMPILE GHC exitFailure = \\ _ _ -> System.Exit.exitFailure #-}"
, Doc
"{-# COMPILE GHC getArgs = fmap (map Data.Text.pack) System.Environment.getArgs #-}"
, Doc
"{-# COMPILE GHC putStrLn = System.IO.putStrLn . Data.Text.unpack #-}"
, Doc
"{-# COMPILE GHC readFiniteFile = Data.Text.IO.readFile . Data.Text.unpack #-}"
]
agdaMainContents
:: String
-> String
-> String
-> String
-> Bool
-> Cat
-> Doc
agdaMainContents :: [Char] -> [Char] -> [Char] -> [Char] -> Bool -> Cat -> Doc
agdaMainContents [Char]
mod [Char]
lmod [Char]
amod [Char]
pmod Bool
layout Cat
c = [Doc] -> Doc
vcat
[ Doc
"-- Test for Agda binding of parser. Requires Agda >= 2.5.4."
, Doc
""
, Doc
"module" Doc -> Doc -> Doc
<+> [Char] -> Doc
text [Char]
mod Doc -> Doc -> Doc
<+> Doc
"where"
, Bool -> Doc -> Doc
forall m. Monoid m => Bool -> m -> m
when Bool
layout Doc
"\nopen import Agda.Builtin.Bool using (true)"
, Doc
"open import" Doc -> Doc -> Doc
<+> [Char] -> Doc
text [Char]
lmod
, Doc
"open import" Doc -> Doc -> Doc
<+> [Char] -> Doc
text [Char]
amod Doc -> Doc -> Doc
<+> Doc
"using" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (Doc
printer)
, Doc
"open import" Doc -> Doc -> Doc
<+> [Char] -> Doc
text [Char]
pmod Doc -> Doc -> Doc
<+> Doc
"using" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (Doc
"Err;" Doc -> Doc -> Doc
<+> Doc
parser)
, Doc
""
, Doc
"main : IO ⊤"
, Doc
"main = do"
, Doc
" file ∷ [] ← getArgs where"
, Doc
" _ → do"
, Doc
" putStrLn \"usage: Main <SourceFile>\""
, Doc
" exitFailure"
, Doc
" Err.ok result ←" Doc -> Doc -> Doc
<+> Doc
parseFun Doc -> Doc -> Doc
<+> Doc
"<$> readFiniteFile file where"
, Doc
" Err.bad msg → do"
, Doc
" putStrLn \"PARSE FAILED\\n\""
, Doc
" putStrLn (stringFromList msg)"
, Doc
" exitFailure"
, Doc
" putStrLn \"PARSE SUCCESSFUL\\n\""
, Doc
" putStrLn" Doc -> Doc -> Doc
<+> Doc -> Doc
parens (Doc
printer Doc -> Doc -> Doc
<+> Doc
"result")
]
where
printer :: Doc
printer = Cat -> Doc
agdaPrinterName Cat
c
parser :: Doc
parser = Cat -> Doc
agdaParserName Cat
c
parseFun :: Doc
parseFun = [Doc] -> Doc
hsep ([Doc] -> Doc) -> ([[Doc]] -> [Doc]) -> [[Doc]] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Doc]] -> [Doc]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Doc]] -> Doc) -> [[Doc]] -> Doc
forall a b. (a -> b) -> a -> b
$ [ [Doc
parser], Bool -> [Doc] -> [Doc]
forall m. Monoid m => Bool -> m -> m
when Bool
layout [Doc
"true"] ]