{- -----------------------------------------------------------------------------
Copyright 2020 Kevin P. Barry

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
----------------------------------------------------------------------------- -}

-- Author: Kevin P. Barry [ta0kira@gmail.com]

module Module.ParseMetadata (
  ConfigFormat,
  autoReadConfig,
  autoWriteConfig,
) where

import Control.Applicative.Permutations
import Control.Monad (when)
import Text.Parsec

import Base.CompileError
import Cli.CompileOptions
import Cli.Programs (VersionHash(..))
import Module.CompileMetadata
import Parser.Common
import Parser.Procedure ()
import Parser.TypeCategory ()
import Parser.TypeInstance ()
import Text.Regex.TDFA -- Not safe!
import Types.Pragma (MacroName)
import Types.Procedure (Expression)
import Types.TypeCategory (FunctionName(..),Namespace(..))
import Types.TypeInstance (CategoryName(..))


class ConfigFormat a where
  readConfig :: CompileErrorM m => ParserE m a
  writeConfig :: CompileErrorM m => a -> m [String]

autoReadConfig :: (ConfigFormat a, CompileErrorM m) => String -> String -> m a
autoReadConfig :: String -> String -> m a
autoReadConfig String
f String
s = ParserE m a -> String -> String -> m a
forall (m :: * -> *) a.
CompileErrorM m =>
ParserE m a -> String -> String -> m a
runParserE (ParsecT String () m ()
-> ParsecT String () m () -> ParserE m a -> ParserE m a
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between ParsecT String () m ()
forall (m :: * -> *). Monad m => ParserE m ()
optionalSpace ParsecT String () m ()
forall (m :: * -> *). Monad m => ParserE m ()
endOfDoc ParserE m a
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
ParserE m a
readConfig) String
f String
s

autoWriteConfig ::  (ConfigFormat a, CompileErrorM m) => a -> m String
autoWriteConfig :: a -> m String
autoWriteConfig = ([String] -> String) -> m [String] -> m String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [String] -> String
unlines (m [String] -> m String) -> (a -> m [String]) -> a -> m String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig

structOpen :: Monad m => ParserE m ()
structOpen :: ParserE m ()
structOpen = ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"{")

structClose :: Monad m => ParserE m ()
structClose :: ParserE m ()
structClose = ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"}")

indents :: [String] -> [String]
indents :: [String] -> [String]
indents = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
indent

indent :: String -> String
indent :: String -> String
indent = (String
"  " String -> String -> String
forall a. [a] -> [a] -> [a]
++)

prependFirst :: String -> [String] -> [String]
prependFirst :: String -> [String] -> [String]
prependFirst String
s0 (String
s:[String]
ss) = (String
s0 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s)String -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
ss
prependFirst String
s0 [String]
_      = [String
s0]

validateCategoryName :: CompileErrorM m => CategoryName -> m ()
validateCategoryName :: CategoryName -> m ()
validateCategoryName CategoryName
c =
    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ CategoryName -> String
forall a. Show a => a -> String
show CategoryName
c String -> String -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^[A-Z][A-Za-z0-9]*$") (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
      String -> m ()
forall (m :: * -> *) a. CompileErrorM m => String -> m a
compileErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Invalid category name: \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ CategoryName -> String
forall a. Show a => a -> String
show CategoryName
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""

validateFunctionName :: CompileErrorM m => FunctionName -> m ()
validateFunctionName :: FunctionName -> m ()
validateFunctionName FunctionName
f =
    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ FunctionName -> String
forall a. Show a => a -> String
show FunctionName
f String -> String -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^[a-z][A-Za-z0-9]*$") (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
      String -> m ()
forall (m :: * -> *) a. CompileErrorM m => String -> m a
compileErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Invalid function name: \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FunctionName -> String
forall a. Show a => a -> String
show FunctionName
f String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""

validateHash :: CompileErrorM m => VersionHash -> m ()
validateHash :: VersionHash -> m ()
validateHash VersionHash
h =
    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ VersionHash -> String
forall a. Show a => a -> String
show VersionHash
h String -> String -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^[A-Za-z0-9]+$") (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
      String -> m ()
forall (m :: * -> *) a. CompileErrorM m => String -> m a
compileErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Version hash must be a hex string: \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ VersionHash -> String
forall a. Show a => a -> String
show VersionHash
h String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""

parseHash :: Monad m => ParserE m VersionHash
parseHash :: ParserE m VersionHash
parseHash = String -> ParserE m VersionHash -> ParserE m VersionHash
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> ParserE m a
labeled String
"version hash" (ParserE m VersionHash -> ParserE m VersionHash)
-> ParserE m VersionHash -> ParserE m VersionHash
forall a b. (a -> b) -> a -> b
$ ParserE m VersionHash -> ParserE m VersionHash
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter ((String -> VersionHash)
-> ParsecT String () m String -> ParserE m VersionHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> VersionHash
VersionHash (ParsecT String () m String -> ParserE m VersionHash)
-> ParsecT String () m String -> ParserE m VersionHash
forall a b. (a -> b) -> a -> b
$ ParsecT String () m Char -> ParsecT String () m String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT String () m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
hexDigit)

maybeShowNamespace :: CompileErrorM m => String -> Namespace -> m [String]
maybeShowNamespace :: String -> Namespace -> m [String]
maybeShowNamespace String
l (StaticNamespace String
ns) = do
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String
ns String -> String -> Bool
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"^[A-Za-z][A-Za-z0-9_]*$") (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
    String -> m ()
forall (m :: * -> *) a. CompileErrorM m => String -> m a
compileErrorM (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
"Invalid category namespace: \"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ns String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\""
  [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return [String
l String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ns]
maybeShowNamespace String
_ Namespace
_ = [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return []

parseNamespace :: Monad m => ParserE m Namespace
parseNamespace :: ParserE m Namespace
parseNamespace = String -> ParserE m Namespace -> ParserE m Namespace
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> ParserE m a
labeled String
"namespace" (ParserE m Namespace -> ParserE m Namespace)
-> ParserE m Namespace -> ParserE m Namespace
forall a b. (a -> b) -> a -> b
$ do
  Char
b <- ParsecT String () m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
lower
  String
e <- ParserE m String -> ParserE m String
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (ParserE m String -> ParserE m String)
-> ParserE m String -> ParserE m String
forall a b. (a -> b) -> a -> b
$ ParsecT String () m Char -> ParserE m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT String () m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum ParsecT String () m Char
-> ParsecT String () m Char -> ParsecT String () m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT String () m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'_')
  Namespace -> ParserE m Namespace
forall (m :: * -> *) a. Monad m => a -> m a
return (Namespace -> ParserE m Namespace)
-> Namespace -> ParserE m Namespace
forall a b. (a -> b) -> a -> b
$ String -> Namespace
StaticNamespace (Char
bChar -> String -> String
forall a. a -> [a] -> [a]
:String
e)

parseQuoted :: Monad m => ParserE m String
parseQuoted :: ParserE m String
parseQuoted = String -> ParserE m String -> ParserE m String
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> ParserE m a
labeled String
"quoted string" (ParserE m String -> ParserE m String)
-> ParserE m String -> ParserE m String
forall a b. (a -> b) -> a -> b
$ do
  String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"\""
  String
ss <- ParsecT String () m Char -> ParserE m () -> ParserE m String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () m Char
forall (m :: * -> *). Monad m => ParserE m Char
stringChar (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"\"")
  ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
optionalSpace
  String -> ParserE m String
forall (m :: * -> *) a. Monad m => a -> m a
return String
ss

parseList :: Monad m => ParserE m a -> ParserE m [a]
parseList :: ParserE m a -> ParserE m [a]
parseList ParserE m a
p = String -> ParserE m [a] -> ParserE m [a]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> ParserE m a
labeled String
"list" (ParserE m [a] -> ParserE m [a]) -> ParserE m [a] -> ParserE m [a]
forall a b. (a -> b) -> a -> b
$ do
  ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"[")
  [a]
xs <- ParserE m a -> ParserE m () -> ParserE m [a]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill (ParserE m a -> ParserE m a
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter ParserE m a
p) (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"]")
  ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
optionalSpace
  [a] -> ParserE m [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [a]
xs

parseOptional :: Monad m => String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional :: String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
l a
def ParserE m a
p = a -> ParserE m a -> Permutation (ParserE m) a
forall (m :: * -> *) a.
Alternative m =>
a -> m a -> Permutation m a
toPermutationWithDefault a
def (ParserE m a -> Permutation (ParserE m) a)
-> ParserE m a -> Permutation (ParserE m) a
forall a b. (a -> b) -> a -> b
$ do
    ParsecT String () m () -> ParsecT String () m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () m () -> ParsecT String () m ())
-> ParsecT String () m () -> ParsecT String () m ()
forall a b. (a -> b) -> a -> b
$ ParsecT String () m () -> ParsecT String () m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParsecT String () m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
l)
    ParserE m a
p

parseRequired :: Monad m => String -> ParserE m a -> Permutation (ParserE m) a
parseRequired :: String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
l ParserE m a
p = ParserE m a -> Permutation (ParserE m) a
forall (m :: * -> *) a. Alternative m => m a -> Permutation m a
toPermutation (ParserE m a -> Permutation (ParserE m) a)
-> ParserE m a -> Permutation (ParserE m) a
forall a b. (a -> b) -> a -> b
$ do
    ParsecT String () m () -> ParsecT String () m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () m () -> ParsecT String () m ())
-> ParsecT String () m () -> ParsecT String () m ()
forall a b. (a -> b) -> a -> b
$ ParsecT String () m () -> ParsecT String () m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParsecT String () m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
l)
    ParserE m a
p

instance ConfigFormat CompileMetadata where
  readConfig :: ParserE m CompileMetadata
readConfig = Permutation (ParserE m) CompileMetadata
-> ParserE m CompileMetadata
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) CompileMetadata
 -> ParserE m CompileMetadata)
-> Permutation (ParserE m) CompileMetadata
-> ParserE m CompileMetadata
forall a b. (a -> b) -> a -> b
$ VersionHash
-> String
-> Namespace
-> Namespace
-> [String]
-> [String]
-> [CategoryName]
-> [CategoryName]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> [String]
-> [ObjectFile]
-> CompileMetadata
CompileMetadata
    (VersionHash
 -> String
 -> Namespace
 -> Namespace
 -> [String]
 -> [String]
 -> [CategoryName]
 -> [CategoryName]
 -> [String]
 -> [String]
 -> [String]
 -> [String]
 -> [String]
 -> [String]
 -> [String]
 -> [String]
 -> [String]
 -> [ObjectFile]
 -> CompileMetadata)
-> Permutation (ParserE m) VersionHash
-> Permutation
     (ParserE m)
     (String
      -> Namespace
      -> Namespace
      -> [String]
      -> [String]
      -> [CategoryName]
      -> [CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> ParserE m VersionHash -> Permutation (ParserE m) VersionHash
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"version_hash:"       ParserE m VersionHash
forall (m :: * -> *). Monad m => ParserE m VersionHash
parseHash
    Permutation
  (ParserE m)
  (String
   -> Namespace
   -> Namespace
   -> [String]
   -> [String]
   -> [CategoryName]
   -> [CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) String
-> Permutation
     (ParserE m)
     (Namespace
      -> Namespace
      -> [String]
      -> [String]
      -> [CategoryName]
      -> [CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"path:"               ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
    Permutation
  (ParserE m)
  (Namespace
   -> Namespace
   -> [String]
   -> [String]
   -> [CategoryName]
   -> [CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) Namespace
-> Permutation
     (ParserE m)
     (Namespace
      -> [String]
      -> [String]
      -> [CategoryName]
      -> [CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> Namespace
-> ParserE m Namespace
-> Permutation (ParserE m) Namespace
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"public_namespace:"   Namespace
NoNamespace ParserE m Namespace
forall (m :: * -> *). Monad m => ParserE m Namespace
parseNamespace
    Permutation
  (ParserE m)
  (Namespace
   -> [String]
   -> [String]
   -> [CategoryName]
   -> [CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) Namespace
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [CategoryName]
      -> [CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> Namespace
-> ParserE m Namespace
-> Permutation (ParserE m) Namespace
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"private_namespace:"  Namespace
NoNamespace ParserE m Namespace
forall (m :: * -> *). Monad m => ParserE m Namespace
parseNamespace
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [CategoryName]
   -> [CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [CategoryName]
      -> [CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"public_deps:"        (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [CategoryName]
   -> [CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([CategoryName]
      -> [CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"private_deps:"       (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([CategoryName]
   -> [CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [CategoryName]
-> Permutation
     (ParserE m)
     ([CategoryName]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m [CategoryName]
-> Permutation (ParserE m) [CategoryName]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"public_categories:"  (ParserE m CategoryName -> ParserE m [CategoryName]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser)
    Permutation
  (ParserE m)
  ([CategoryName]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [CategoryName]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m [CategoryName]
-> Permutation (ParserE m) [CategoryName]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"private_categories:" (ParserE m CategoryName -> ParserE m [CategoryName]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"public_subdirs:"     (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"private_subdirs:"    (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"public_files:"       (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"private_files:"      (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [String]
      -> [String]
      -> [ObjectFile]
      -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"test_files:"         (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [String]
   -> [String]
   -> [ObjectFile]
   -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [String] -> [String] -> [ObjectFile] -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"hxx_files:"          (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [String] -> [String] -> [ObjectFile] -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String] -> [String] -> [ObjectFile] -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"cxx_files:"          (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String] -> [String] -> [ObjectFile] -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m) ([String] -> [ObjectFile] -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"binaries:"           (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m) ([String] -> [ObjectFile] -> CompileMetadata)
-> Permutation (ParserE m) [String]
-> Permutation (ParserE m) ([ObjectFile] -> CompileMetadata)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"link_flags:"         (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation (ParserE m) ([ObjectFile] -> CompileMetadata)
-> Permutation (ParserE m) [ObjectFile]
-> Permutation (ParserE m) CompileMetadata
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m [ObjectFile] -> Permutation (ParserE m) [ObjectFile]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"object_files:"       (ParserE m ObjectFile -> ParserE m [ObjectFile]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m ObjectFile
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
ParserE m a
readConfig)
  writeConfig :: CompileMetadata -> m [String]
writeConfig (CompileMetadata VersionHash
h String
p Namespace
ns1 Namespace
ns2 [String]
is [String]
is2 [CategoryName]
cs1 [CategoryName]
cs2 [String]
ds1 [String]
ds2 [String]
ps [String]
xs [String]
ts [String]
hxx [String]
cxx [String]
bs [String]
lf [ObjectFile]
os) = do
    VersionHash -> m ()
forall (m :: * -> *). CompileErrorM m => VersionHash -> m ()
validateHash VersionHash
h
    [String]
ns1' <- String -> Namespace -> m [String]
forall (m :: * -> *).
CompileErrorM m =>
String -> Namespace -> m [String]
maybeShowNamespace String
"public_namespace:"  Namespace
ns1
    [String]
ns2' <- String -> Namespace -> m [String]
forall (m :: * -> *).
CompileErrorM m =>
String -> Namespace -> m [String]
maybeShowNamespace String
"private_namespace:" Namespace
ns2
    (CategoryName -> m ()) -> [CategoryName] -> m ()
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName [CategoryName]
cs1
    (CategoryName -> m ()) -> [CategoryName] -> m ()
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName [CategoryName]
cs2
    [String]
os' <- ([[String]] -> [String]) -> m [[String]] -> m [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (m [[String]] -> m [String]) -> m [[String]] -> m [String]
forall a b. (a -> b) -> a -> b
$ (ObjectFile -> m [String]) -> [ObjectFile] -> m [[String]]
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m [b]
mapErrorsM ObjectFile -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig [ObjectFile]
os
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"version_hash: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ VersionHash -> String
forall a. Show a => a -> String
show VersionHash
h,
        String
"path: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
p
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
ns1' [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
ns2' [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"public_deps: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
is) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"private_deps: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
is2) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"public_categories: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((CategoryName -> String) -> [CategoryName] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map CategoryName -> String
forall a. Show a => a -> String
show [CategoryName]
cs1) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"private_categories: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((CategoryName -> String) -> [CategoryName] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map CategoryName -> String
forall a. Show a => a -> String
show [CategoryName]
cs2) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"public_subdirs: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
ds1) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"private_subdirs: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
ds2) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"public_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
ps) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"private_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
xs) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"test_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
ts) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"hxx_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
hxx) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"cxx_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
cxx) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"binaries: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
bs) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"link_flags: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
lf) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"object_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents [String]
os' [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]"
      ]

instance ConfigFormat ObjectFile where
  readConfig :: ParserE m ObjectFile
readConfig = ParserE m ObjectFile
category ParserE m ObjectFile
-> ParserE m ObjectFile -> ParserE m ObjectFile
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParserE m ObjectFile
other where
    category :: ParserE m ObjectFile
category = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"category_object")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      ObjectFile
o <- Permutation (ParserE m) ObjectFile -> ParserE m ObjectFile
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) ObjectFile -> ParserE m ObjectFile)
-> Permutation (ParserE m) ObjectFile -> ParserE m ObjectFile
forall a b. (a -> b) -> a -> b
$ CategoryIdentifier
-> [CategoryIdentifier] -> [String] -> ObjectFile
CategoryObjectFile
        (CategoryIdentifier
 -> [CategoryIdentifier] -> [String] -> ObjectFile)
-> Permutation (ParserE m) CategoryIdentifier
-> Permutation
     (ParserE m) ([CategoryIdentifier] -> [String] -> ObjectFile)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> ParserE m CategoryIdentifier
-> Permutation (ParserE m) CategoryIdentifier
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"category:" ParserE m CategoryIdentifier
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
ParserE m a
readConfig
        Permutation
  (ParserE m) ([CategoryIdentifier] -> [String] -> ObjectFile)
-> Permutation (ParserE m) [CategoryIdentifier]
-> Permutation (ParserE m) ([String] -> ObjectFile)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m [CategoryIdentifier]
-> Permutation (ParserE m) [CategoryIdentifier]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"requires:" (ParserE m CategoryIdentifier -> ParserE m [CategoryIdentifier]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m CategoryIdentifier
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
ParserE m a
readConfig)
        Permutation (ParserE m) ([String] -> ObjectFile)
-> Permutation (ParserE m) [String]
-> Permutation (ParserE m) ObjectFile
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m [String] -> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"files:"    (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      ObjectFile -> ParserE m ObjectFile
forall (m :: * -> *) a. Monad m => a -> m a
return ObjectFile
o
    other :: ParserE m ObjectFile
other = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"other_object")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      ObjectFile
f <- Permutation (ParserE m) ObjectFile -> ParserE m ObjectFile
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) ObjectFile -> ParserE m ObjectFile)
-> Permutation (ParserE m) ObjectFile -> ParserE m ObjectFile
forall a b. (a -> b) -> a -> b
$ String -> ObjectFile
OtherObjectFile
        (String -> ObjectFile)
-> Permutation (ParserE m) String
-> Permutation (ParserE m) ObjectFile
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"file:" ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      ObjectFile -> ParserE m ObjectFile
forall (m :: * -> *) a. Monad m => a -> m a
return ObjectFile
f
  writeConfig :: ObjectFile -> m [String]
writeConfig (CategoryObjectFile CategoryIdentifier
c [CategoryIdentifier]
rs [String]
fs) = do
    [String]
category <- CategoryIdentifier -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig CategoryIdentifier
c
    [String]
requires <- ([[String]] -> [String]) -> m [[String]] -> m [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (m [[String]] -> m [String]) -> m [[String]] -> m [String]
forall a b. (a -> b) -> a -> b
$ (CategoryIdentifier -> m [String])
-> [CategoryIdentifier] -> m [[String]]
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m [b]
mapErrorsM CategoryIdentifier -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig [CategoryIdentifier]
rs
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"category_object {"
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents (String
"category: " String -> [String] -> [String]
`prependFirst` [String]
category) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"requires: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
indents ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
indents) [String]
requires [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"]",
        String -> String
indent String
"files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
indents ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
indents) ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
fs) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"]",
        String
"}"
      ]
  writeConfig (OtherObjectFile String
f) = do
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"other_object {",
        String -> String
indent (String
"file: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
f),
        String
"}"
      ]

instance ConfigFormat CategoryIdentifier where
  readConfig :: ParserE m CategoryIdentifier
readConfig = ParserE m CategoryIdentifier
category ParserE m CategoryIdentifier
-> ParserE m CategoryIdentifier -> ParserE m CategoryIdentifier
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParserE m CategoryIdentifier
unresolved where
    category :: ParserE m CategoryIdentifier
category = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"category")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      CategoryIdentifier
i <- Permutation (ParserE m) CategoryIdentifier
-> ParserE m CategoryIdentifier
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) CategoryIdentifier
 -> ParserE m CategoryIdentifier)
-> Permutation (ParserE m) CategoryIdentifier
-> ParserE m CategoryIdentifier
forall a b. (a -> b) -> a -> b
$ String -> CategoryName -> Namespace -> CategoryIdentifier
CategoryIdentifier
        (String -> CategoryName -> Namespace -> CategoryIdentifier)
-> Permutation (ParserE m) String
-> Permutation
     (ParserE m) (CategoryName -> Namespace -> CategoryIdentifier)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"path:"      ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
        Permutation
  (ParserE m) (CategoryName -> Namespace -> CategoryIdentifier)
-> Permutation (ParserE m) CategoryName
-> Permutation (ParserE m) (Namespace -> CategoryIdentifier)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m CategoryName -> Permutation (ParserE m) CategoryName
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"name:"      ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser
        Permutation (ParserE m) (Namespace -> CategoryIdentifier)
-> Permutation (ParserE m) Namespace
-> Permutation (ParserE m) CategoryIdentifier
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> Namespace
-> ParserE m Namespace
-> Permutation (ParserE m) Namespace
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"namespace:" Namespace
NoNamespace ParserE m Namespace
forall (m :: * -> *). Monad m => ParserE m Namespace
parseNamespace
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      CategoryIdentifier -> ParserE m CategoryIdentifier
forall (m :: * -> *) a. Monad m => a -> m a
return CategoryIdentifier
i
    unresolved :: ParserE m CategoryIdentifier
unresolved = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"unresolved")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      CategoryIdentifier
c <- Permutation (ParserE m) CategoryIdentifier
-> ParserE m CategoryIdentifier
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) CategoryIdentifier
 -> ParserE m CategoryIdentifier)
-> Permutation (ParserE m) CategoryIdentifier
-> ParserE m CategoryIdentifier
forall a b. (a -> b) -> a -> b
$ CategoryName -> CategoryIdentifier
UnresolvedCategory
        (CategoryName -> CategoryIdentifier)
-> Permutation (ParserE m) CategoryName
-> Permutation (ParserE m) CategoryIdentifier
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> ParserE m CategoryName -> Permutation (ParserE m) CategoryName
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"name:" ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      CategoryIdentifier -> ParserE m CategoryIdentifier
forall (m :: * -> *) a. Monad m => a -> m a
return CategoryIdentifier
c
  writeConfig :: CategoryIdentifier -> m [String]
writeConfig (CategoryIdentifier String
p CategoryName
c Namespace
ns) = do
    CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName CategoryName
c
    [String]
namespace <- String -> Namespace -> m [String]
forall (m :: * -> *).
CompileErrorM m =>
String -> Namespace -> m [String]
maybeShowNamespace String
"namespace:" Namespace
ns
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"category {",
        String -> String
indent (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"name: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ CategoryName -> String
forall a. Show a => a -> String
show CategoryName
c
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents [String]
namespace [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"path: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
p,
        String
"}"
      ]
  writeConfig (UnresolvedCategory CategoryName
c) = do
    CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName CategoryName
c
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [String
"unresolved { " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"name: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ CategoryName -> String
forall a. Show a => a -> String
show CategoryName
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"]

instance ConfigFormat ModuleConfig where
  readConfig :: ParserE m ModuleConfig
readConfig = Permutation (ParserE m) ModuleConfig -> ParserE m ModuleConfig
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) ModuleConfig -> ParserE m ModuleConfig)
-> Permutation (ParserE m) ModuleConfig -> ParserE m ModuleConfig
forall a b. (a -> b) -> a -> b
$ String
-> String
-> [(MacroName, Expression SourcePos)]
-> [String]
-> [String]
-> [ExtraSource]
-> [String]
-> CompileMode
-> ModuleConfig
ModuleConfig
    (String
 -> String
 -> [(MacroName, Expression SourcePos)]
 -> [String]
 -> [String]
 -> [ExtraSource]
 -> [String]
 -> CompileMode
 -> ModuleConfig)
-> Permutation (ParserE m) String
-> Permutation
     (ParserE m)
     (String
      -> [(MacroName, Expression SourcePos)]
      -> [String]
      -> [String]
      -> [ExtraSource]
      -> [String]
      -> CompileMode
      -> ModuleConfig)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"root:"           String
"" ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
    Permutation
  (ParserE m)
  (String
   -> [(MacroName, Expression SourcePos)]
   -> [String]
   -> [String]
   -> [ExtraSource]
   -> [String]
   -> CompileMode
   -> ModuleConfig)
-> Permutation (ParserE m) String
-> Permutation
     (ParserE m)
     ([(MacroName, Expression SourcePos)]
      -> [String]
      -> [String]
      -> [ExtraSource]
      -> [String]
      -> CompileMode
      -> ModuleConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"path:"              ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
    Permutation
  (ParserE m)
  ([(MacroName, Expression SourcePos)]
   -> [String]
   -> [String]
   -> [ExtraSource]
   -> [String]
   -> CompileMode
   -> ModuleConfig)
-> Permutation (ParserE m) [(MacroName, Expression SourcePos)]
-> Permutation
     (ParserE m)
     ([String]
      -> [String]
      -> [ExtraSource]
      -> [String]
      -> CompileMode
      -> ModuleConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [(MacroName, Expression SourcePos)]
-> ParserE m [(MacroName, Expression SourcePos)]
-> Permutation (ParserE m) [(MacroName, Expression SourcePos)]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"expression_map:" [] (ParserE m (MacroName, Expression SourcePos)
-> ParserE m [(MacroName, Expression SourcePos)]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m (MacroName, Expression SourcePos)
forall (m :: * -> *).
CompileErrorM m =>
ParserE m (MacroName, Expression SourcePos)
parseExprMacro)
    Permutation
  (ParserE m)
  ([String]
   -> [String]
   -> [ExtraSource]
   -> [String]
   -> CompileMode
   -> ModuleConfig)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([String]
      -> [ExtraSource] -> [String] -> CompileMode -> ModuleConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [String]
-> ParserE m [String]
-> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"public_deps:"    [] (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([String]
   -> [ExtraSource] -> [String] -> CompileMode -> ModuleConfig)
-> Permutation (ParserE m) [String]
-> Permutation
     (ParserE m)
     ([ExtraSource] -> [String] -> CompileMode -> ModuleConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [String]
-> ParserE m [String]
-> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"private_deps:"   [] (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation
  (ParserE m)
  ([ExtraSource] -> [String] -> CompileMode -> ModuleConfig)
-> Permutation (ParserE m) [ExtraSource]
-> Permutation
     (ParserE m) ([String] -> CompileMode -> ModuleConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [ExtraSource]
-> ParserE m [ExtraSource]
-> Permutation (ParserE m) [ExtraSource]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"extra_files:"    [] (ParserE m ExtraSource -> ParserE m [ExtraSource]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m ExtraSource
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
ParserE m a
readConfig)
    Permutation (ParserE m) ([String] -> CompileMode -> ModuleConfig)
-> Permutation (ParserE m) [String]
-> Permutation (ParserE m) (CompileMode -> ModuleConfig)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [String]
-> ParserE m [String]
-> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"include_paths:"  [] (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
    Permutation (ParserE m) (CompileMode -> ModuleConfig)
-> Permutation (ParserE m) CompileMode
-> Permutation (ParserE m) ModuleConfig
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m CompileMode -> Permutation (ParserE m) CompileMode
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"mode:"              ParserE m CompileMode
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
ParserE m a
readConfig
  writeConfig :: ModuleConfig -> m [String]
writeConfig (ModuleConfig String
p String
d [(MacroName, Expression SourcePos)]
em [String]
is [String]
is2 [ExtraSource]
es [String]
ep CompileMode
m) = do
    [String]
es' <- ([[String]] -> [String]) -> m [[String]] -> m [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[String]] -> [String]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (m [[String]] -> m [String]) -> m [[String]] -> m [String]
forall a b. (a -> b) -> a -> b
$ (ExtraSource -> m [String]) -> [ExtraSource] -> m [[String]]
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m [b]
mapErrorsM ExtraSource -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig [ExtraSource]
es
    [String]
m' <- CompileMode -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig CompileMode
m
    Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [(MacroName, Expression SourcePos)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(MacroName, Expression SourcePos)]
em) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *) a. CompileErrorM m => String -> m a
compileErrorM String
"Only empty expression maps are allowed when writing"
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"root: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
p,
        String
"path: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
d,
        String
"expression_map: [",
        -- NOTE: expression_map isn't output because that would require making
        -- all Expression serializable.
        String
"]",
        String
"public_deps: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
is) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"private_deps: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
is2) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"extra_files: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents [String]
es' [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]",
        String
"include_paths: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String] -> [String]
indents ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
ep) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String
"]"
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ String
"mode: " String -> [String] -> [String]
`prependFirst` [String]
m'

instance ConfigFormat ExtraSource where
  readConfig :: ParserE m ExtraSource
readConfig = ParserE m ExtraSource
category ParserE m ExtraSource
-> ParserE m ExtraSource -> ParserE m ExtraSource
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParserE m ExtraSource
other where
    category :: ParserE m ExtraSource
category = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"category_source")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      ExtraSource
s <- Permutation (ParserE m) ExtraSource -> ParserE m ExtraSource
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) ExtraSource -> ParserE m ExtraSource)
-> Permutation (ParserE m) ExtraSource -> ParserE m ExtraSource
forall a b. (a -> b) -> a -> b
$ String -> [CategoryName] -> [CategoryName] -> ExtraSource
CategorySource
        (String -> [CategoryName] -> [CategoryName] -> ExtraSource)
-> Permutation (ParserE m) String
-> Permutation
     (ParserE m) ([CategoryName] -> [CategoryName] -> ExtraSource)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"source:"        ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
        Permutation
  (ParserE m) ([CategoryName] -> [CategoryName] -> ExtraSource)
-> Permutation (ParserE m) [CategoryName]
-> Permutation (ParserE m) ([CategoryName] -> ExtraSource)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [CategoryName]
-> ParserE m [CategoryName]
-> Permutation (ParserE m) [CategoryName]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"categories:" [] (ParserE m CategoryName -> ParserE m [CategoryName]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser)
        Permutation (ParserE m) ([CategoryName] -> ExtraSource)
-> Permutation (ParserE m) [CategoryName]
-> Permutation (ParserE m) ExtraSource
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [CategoryName]
-> ParserE m [CategoryName]
-> Permutation (ParserE m) [CategoryName]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"requires:"   [] (ParserE m CategoryName -> ParserE m [CategoryName]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser)
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      ExtraSource -> ParserE m ExtraSource
forall (m :: * -> *) a. Monad m => a -> m a
return ExtraSource
s
    other :: ParserE m ExtraSource
other = do
      String
f <- ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
      ExtraSource -> ParserE m ExtraSource
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> ExtraSource
OtherSource String
f)
  writeConfig :: ExtraSource -> m [String]
writeConfig (CategorySource String
f [CategoryName]
cs [CategoryName]
ds) = do
    (CategoryName -> m ()) -> [CategoryName] -> m ()
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName [CategoryName]
cs
    (CategoryName -> m ()) -> [CategoryName] -> m ()
forall (m :: * -> *) a b.
CompileErrorM m =>
(a -> m b) -> [a] -> m ()
mapErrorsM_ CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName [CategoryName]
ds
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"category_source {",
        String -> String
indent (String
"source: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
f),
        String -> String
indent String
"categories: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
indents ([String] -> [String])
-> ([CategoryName] -> [String]) -> [CategoryName] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
indents ([String] -> [String])
-> ([CategoryName] -> [String]) -> [CategoryName] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CategoryName -> String) -> [CategoryName] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map CategoryName -> String
forall a. Show a => a -> String
show) [CategoryName]
cs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"]",
        String -> String
indent String
"requires: ["
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
indents ([String] -> [String])
-> ([CategoryName] -> [String]) -> [CategoryName] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
indents ([String] -> [String])
-> ([CategoryName] -> [String]) -> [CategoryName] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CategoryName -> String) -> [CategoryName] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map CategoryName -> String
forall a. Show a => a -> String
show) [CategoryName]
ds [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"]",
        String
"}"
      ]
  writeConfig (OtherSource String
f) = [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return [String -> String
forall a. Show a => a -> String
show String
f]

instance ConfigFormat CompileMode where
  readConfig :: ParserE m CompileMode
readConfig = String -> ParserE m CompileMode -> ParserE m CompileMode
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> ParserE m a
labeled String
"compile mode" (ParserE m CompileMode -> ParserE m CompileMode)
-> ParserE m CompileMode -> ParserE m CompileMode
forall a b. (a -> b) -> a -> b
$ ParserE m CompileMode
binary ParserE m CompileMode
-> ParserE m CompileMode -> ParserE m CompileMode
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParserE m CompileMode
incremental where
    binary :: ParserE m CompileMode
binary = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"binary")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      CompileMode
b <- Permutation (ParserE m) CompileMode -> ParserE m CompileMode
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) CompileMode -> ParserE m CompileMode)
-> Permutation (ParserE m) CompileMode -> ParserE m CompileMode
forall a b. (a -> b) -> a -> b
$ CategoryName -> FunctionName -> String -> [String] -> CompileMode
CompileBinary
        (CategoryName -> FunctionName -> String -> [String] -> CompileMode)
-> Permutation (ParserE m) CategoryName
-> Permutation
     (ParserE m) (FunctionName -> String -> [String] -> CompileMode)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> ParserE m CategoryName -> Permutation (ParserE m) CategoryName
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"category:"      ParserE m CategoryName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser
        Permutation
  (ParserE m) (FunctionName -> String -> [String] -> CompileMode)
-> Permutation (ParserE m) FunctionName
-> Permutation (ParserE m) (String -> [String] -> CompileMode)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m FunctionName -> Permutation (ParserE m) FunctionName
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"function:"      ParserE m FunctionName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser
        Permutation (ParserE m) (String -> [String] -> CompileMode)
-> Permutation (ParserE m) String
-> Permutation (ParserE m) ([String] -> CompileMode)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> String -> ParserE m String -> Permutation (ParserE m) String
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"output:"     String
"" ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted
        Permutation (ParserE m) ([String] -> CompileMode)
-> Permutation (ParserE m) [String]
-> Permutation (ParserE m) CompileMode
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> [String]
-> ParserE m [String]
-> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"link_flags:" [] (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      CompileMode -> ParserE m CompileMode
forall (m :: * -> *) a. Monad m => a -> m a
return CompileMode
b
    incremental :: ParserE m CompileMode
incremental = do
      ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"incremental")
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
      CompileMode
lf <- Permutation (ParserE m) CompileMode -> ParserE m CompileMode
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) CompileMode -> ParserE m CompileMode)
-> Permutation (ParserE m) CompileMode -> ParserE m CompileMode
forall a b. (a -> b) -> a -> b
$ [String] -> CompileMode
CompileIncremental
        ([String] -> CompileMode)
-> Permutation (ParserE m) [String]
-> Permutation (ParserE m) CompileMode
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String
-> [String]
-> ParserE m [String]
-> Permutation (ParserE m) [String]
forall (m :: * -> *) a.
Monad m =>
String -> a -> ParserE m a -> Permutation (ParserE m) a
parseOptional String
"link_flags:" [] (ParserE m String -> ParserE m [String]
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m [a]
parseList ParserE m String
forall (m :: * -> *). Monad m => ParserE m String
parseQuoted)
      ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
      CompileMode -> ParserE m CompileMode
forall (m :: * -> *) a. Monad m => a -> m a
return CompileMode
lf
  writeConfig :: CompileMode -> m [String]
writeConfig (CompileBinary CategoryName
c FunctionName
f String
o [String]
lf) = do
    CategoryName -> m ()
forall (m :: * -> *). CompileErrorM m => CategoryName -> m ()
validateCategoryName CategoryName
c
    FunctionName -> m ()
forall (m :: * -> *). CompileErrorM m => FunctionName -> m ()
validateFunctionName FunctionName
f
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"binary {",
        String -> String
indent (String
"category: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ CategoryName -> String
forall a. Show a => a -> String
show CategoryName
c),
        String -> String
indent (String
"function: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ FunctionName -> String
forall a. Show a => a -> String
show FunctionName
f),
        String -> String
indent (String
"output: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
o),
        String -> String
indent (String
"link_flags: [")
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
indents ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
indents) ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
lf) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"]",
        String
"}"
      ]
  writeConfig (CompileIncremental [String]
lf) = do
    [String] -> m [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> m [String]) -> [String] -> m [String]
forall a b. (a -> b) -> a -> b
$ [
        String
"incremental {",
        String -> String
indent (String
"link_flags: [")
      ] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ([String] -> [String]
indents ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
indents) ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
forall a. Show a => a -> String
show [String]
lf) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [
        String -> String
indent String
"]",
        String
"}"
      ]
  writeConfig CompileMode
CompileUnspecified = CompileMode -> m [String]
forall a (m :: * -> *).
(ConfigFormat a, CompileErrorM m) =>
a -> m [String]
writeConfig ([String] -> CompileMode
CompileIncremental [])
  writeConfig CompileMode
_ = String -> m [String]
forall (m :: * -> *) a. CompileErrorM m => String -> m a
compileErrorM String
"Invalid compile mode"

parseExprMacro :: CompileErrorM m => ParserE m (MacroName,Expression SourcePos)
parseExprMacro :: ParserE m (MacroName, Expression SourcePos)
parseExprMacro = do
  ParserE m () -> ParserE m ()
forall (m :: * -> *) a. Monad m => ParserE m a -> ParserE m a
sepAfter (String -> ParserE m ()
forall (m :: * -> *). Monad m => String -> ParserE m ()
string_ String
"expression_macro")
  ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structOpen
  (MacroName, Expression SourcePos)
e <- Permutation (ParserE m) (MacroName, Expression SourcePos)
-> ParserE m (MacroName, Expression SourcePos)
forall (m :: * -> *) a.
(Alternative m, Monad m) =>
Permutation m a -> m a
runPermutation (Permutation (ParserE m) (MacroName, Expression SourcePos)
 -> ParserE m (MacroName, Expression SourcePos))
-> Permutation (ParserE m) (MacroName, Expression SourcePos)
-> ParserE m (MacroName, Expression SourcePos)
forall a b. (a -> b) -> a -> b
$ (,)
    (MacroName
 -> Expression SourcePos -> (MacroName, Expression SourcePos))
-> Permutation (ParserE m) MacroName
-> Permutation
     (ParserE m)
     (Expression SourcePos -> (MacroName, Expression SourcePos))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParserE m MacroName -> Permutation (ParserE m) MacroName
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"name:"       ParserE m MacroName
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser
    Permutation
  (ParserE m)
  (Expression SourcePos -> (MacroName, Expression SourcePos))
-> Permutation (ParserE m) (Expression SourcePos)
-> Permutation (ParserE m) (MacroName, Expression SourcePos)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String
-> ParserE m (Expression SourcePos)
-> Permutation (ParserE m) (Expression SourcePos)
forall (m :: * -> *) a.
Monad m =>
String -> ParserE m a -> Permutation (ParserE m) a
parseRequired String
"expression:" ParserE m (Expression SourcePos)
forall a (m :: * -> *).
(ParseFromSource a, CompileErrorM m) =>
ParserE m a
sourceParser
  ParserE m ()
forall (m :: * -> *). Monad m => ParserE m ()
structClose
  (MacroName, Expression SourcePos)
-> ParserE m (MacroName, Expression SourcePos)
forall (m :: * -> *) a. Monad m => a -> m a
return (MacroName, Expression SourcePos)
e