{-# LANGUAGE PatternSynonyms, FlexibleContexts, QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
-- | Defines generation functions for SCS code packages.
module Language.Drasil.Code.Imperative.Generator (
  SomeProgGenerator(..),
  generator, generateCode, generateCodeProc, toFileLayout
) where

import Control.Lens ((^.))
import Control.Monad.State (get, evalState, runState)
import qualified Data.Set as Set (fromList)
import Data.Map (fromList, member, keys, elems)
import qualified Data.Map as M
import Data.Maybe (maybeToList, catMaybes)
import Text.PrettyPrint.HughesPJ (empty, isEmpty, vcat)

import Drasil.FileHandling (FileLayout, file, directory, exactFile, ps)
import Language.Drasil
import Drasil.GOOL (OOProg, File, FS, VisibilityTag(..), headers, sources,
  mainMod, ProgData(..), initialState, FileData(..), modDoc)
import qualified Drasil.GOOL as OO (GSProgram, ProgramSym(..), unCI)
import Drasil.GProc (ProcProg, NativeVector)
import qualified Drasil.GProc as Proc (GSProgram, ProgramSym(..))
import Language.Drasil.Printers (piSys, Notation(..), oneLineSentenceDoc)
import Drasil.System (HasSystemMeta(..))
import Drasil.SRS (HasSmithEtAlSRS(..))

import Language.Drasil.Code.Imperative.ConceptMatch (chooseConcept)
import Language.Drasil.Code.Imperative.Descriptions (unmodularDesc)
import Language.Drasil.Code.Imperative.SpaceMatch (chooseSpace)
import Language.Drasil.Code.Imperative.GenerateGOOL (ClassType(..),
  genDoxConfig, genReadMe, genModuleWithImports, genModuleWithImportsProc)
import Language.Drasil.Code.Imperative.GenODE (chooseODELib)
import Language.Drasil.Code.Imperative.Helpers (liftS)
import Language.Drasil.Code.Imperative.Import (genModDef, genModDefProc,
  genModFuncs, genModFuncsProc, genModClasses)
import Language.Drasil.Code.Imperative.Modules (genInputMod, genInputModProc,
  genConstClass, genConstMod, checkConstClass, genInputClass,
  genInputConstraints, genInputConstraintsProc, genInputDerived,
  genInputDerivedProc, genInputFormat, genInputFormatProc, genMain, genMainProc,
  genMainFunc, genMainFuncProc, genCalcMod, genCalcModProc, genCalcFunc,
  genCalcFuncProc, genOutputFormat, genOutputFormatProc, genOutputMod,
  genOutputModProc, genSampleInput)
import Language.Drasil.Code.Imperative.DrasilState (GenState, DrasilState(..),
  ScopeType(..), designLog, modExportMap, clsDefMap, genICName,
  makeSoftwareDossierInfo, makeChoicesInfo, HasChoices(..))
import Language.Drasil.SoftwareDossier.SoftwareDossierSym (makeSds,
  SoftwareDossierSym(..))
import Language.Drasil.Code.Imperative.README.Core (ReadMeInfo(..))
import Language.Drasil.Code.PackageData (PackageData(..), pattern PackageData,
  package)
import Language.Drasil.SoftwareDossier.FileNames(sampleInputName)
import Language.Drasil.Code.ExtLibImport (auxMods, imports, modExports)
import Language.Drasil.Code.Lang (Lang(..))
import Language.Drasil.Choices (Choices(..), Modularity(..), Architecture(..),
  Visibility(..), DataInfo(..), Constraints(..), choicesSent, DocConfig(..),
  LogConfig(..), OptionalFeatures(..), InternalConcept(..))
import Language.Drasil.CodeSpec (CodeSpec, HasCodeSpec(..), getODE)

-- | Initializes the generator's 'DrasilState'.
-- 'String' parameter is a string representing the date.
-- \['Expr'\] parameter is the sample input values provided by the user.
generator :: Lang -> String -> [Expr] -> Choices -> CodeSpec -> DrasilState
generator :: Lang -> Name -> [Expr] -> Choices -> CodeSpec -> DrasilState
generator Lang
l Name
dt [Expr]
sd Choices
chs CodeSpec
cs = let
  sdsInfo :: SoftwareDossierInfo
sdsInfo = Verbosity -> [SoftwareDossierFile] -> [Expr] -> SoftwareDossierInfo
makeSoftwareDossierInfo
    (DocConfig -> Verbosity
doxVerbosity (DocConfig -> Verbosity) -> DocConfig -> Verbosity
forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> DocConfig
docConfig (OptionalFeatures -> DocConfig) -> OptionalFeatures -> DocConfig
forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs) (OptionalFeatures -> [SoftwareDossierFile]
auxFiles (OptionalFeatures -> [SoftwareDossierFile])
-> OptionalFeatures -> [SoftwareDossierFile]
forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs) [Expr]
sd
  choices :: ChoicesInfo
choices = Modularity
-> ImplementationType
-> Structure
-> ConstantStructure
-> ConstantRepr
-> MatchedConceptMap
-> MatchedSpaces
-> ConstraintBehaviour
-> ConstraintBehaviour
-> [Comments]
-> Name
-> Name
-> [Logging]
-> (InternalConcept -> Name)
-> ChoicesInfo
makeChoicesInfo
    (Architecture -> Modularity
modularity (Architecture -> Modularity) -> Architecture -> Modularity
forall a b. (a -> b) -> a -> b
$ Choices -> Architecture
architecture Choices
chs)
    (Architecture -> ImplementationType
impType (Architecture -> ImplementationType)
-> Architecture -> ImplementationType
forall a b. (a -> b) -> a -> b
$ Choices -> Architecture
architecture Choices
chs)
    (DataInfo -> Structure
inputStructure (DataInfo -> Structure) -> DataInfo -> Structure
forall a b. (a -> b) -> a -> b
$ Choices -> DataInfo
dataInfo Choices
chs)
    (DataInfo -> ConstantStructure
constStructure (DataInfo -> ConstantStructure) -> DataInfo -> ConstantStructure
forall a b. (a -> b) -> a -> b
$ Choices -> DataInfo
dataInfo Choices
chs)
    (DataInfo -> ConstantRepr
constRepr (DataInfo -> ConstantRepr) -> DataInfo -> ConstantRepr
forall a b. (a -> b) -> a -> b
$ Choices -> DataInfo
dataInfo Choices
chs)
    MatchedConceptMap
mcm
    (Lang -> Choices -> MatchedSpaces
chooseSpace Lang
l Choices
chs)
    (Constraints -> ConstraintBehaviour
onSfwrConstraint (Constraints -> ConstraintBehaviour)
-> Constraints -> ConstraintBehaviour
forall a b. (a -> b) -> a -> b
$ Choices -> Constraints
srsConstraints Choices
chs)
    (Constraints -> ConstraintBehaviour
onPhysConstraint (Constraints -> ConstraintBehaviour)
-> Constraints -> ConstraintBehaviour
forall a b. (a -> b) -> a -> b
$ Choices -> Constraints
srsConstraints Choices
chs)
    (DocConfig -> [Comments]
comments (DocConfig -> [Comments]) -> DocConfig -> [Comments]
forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> DocConfig
docConfig (OptionalFeatures -> DocConfig) -> OptionalFeatures -> DocConfig
forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs)
    (Visibility -> Name
showDate (Visibility -> Name) -> Visibility -> Name
forall a b. (a -> b) -> a -> b
$ DocConfig -> Visibility
dates (DocConfig -> Visibility) -> DocConfig -> Visibility
forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> DocConfig
docConfig (OptionalFeatures -> DocConfig) -> OptionalFeatures -> DocConfig
forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs)
    (LogConfig -> Name
logFile (LogConfig -> Name) -> LogConfig -> Name
forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> LogConfig
logConfig (OptionalFeatures -> LogConfig) -> OptionalFeatures -> LogConfig
forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs)
    (LogConfig -> [Logging]
logging (LogConfig -> [Logging]) -> LogConfig -> [Logging]
forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> LogConfig
logConfig (OptionalFeatures -> LogConfig) -> OptionalFeatures -> LogConfig
forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs)
    (Choices -> InternalConcept -> Name
icNames Choices
chs)
  in DrasilState {
  -- constants
  _dsCodeSpec :: CodeSpec
_dsCodeSpec = CodeSpec
cs,
  printfo :: PrintingInformation
printfo = PrintingInformation
pinfo,
  _choices :: ChoicesInfo
_choices = ChoicesInfo
choices,
  modules :: [Mod]
modules = [Mod]
modules',
  extLibNames :: [(Name, Name)]
extLibNames = [(Name, Name)]
nms,
  extLibMap :: ExtLibMap
extLibMap = [(Name, ExtLibState)] -> ExtLibMap
forall k a. Ord k => [(k, a)] -> Map k a
fromList [(Name, ExtLibState)]
elmap,
  libPaths :: [Name]
libPaths = Maybe Name -> [Name]
forall a. Maybe a -> [a]
maybeToList Maybe Name
pth,
  eMap :: ModExportMap
eMap = ModExportMap
mem,
  libEMap :: ModExportMap
libEMap = ModExportMap
lem,
  clsMap :: ModExportMap
clsMap = ModExportMap
cdm,
  defSet :: Set Name
defSet = [Name] -> Set Name
forall a. Ord a => [a] -> Set a
Set.fromList ([Name] -> Set Name) -> [Name] -> Set Name
forall a b. (a -> b) -> a -> b
$ ModExportMap -> [Name]
forall k a. Map k a -> [k]
keys ModExportMap
mem [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ ModExportMap -> [Name]
forall k a. Map k a -> [k]
keys ModExportMap
cdm,
  getVal :: Int
getVal = Choices -> Int
folderVal Choices
chs,
  _softwareDossierInfo :: SoftwareDossierInfo
_softwareDossierInfo = SoftwareDossierInfo
sdsInfo,
  -- stateful
  currentModule :: Name
currentModule = Name
"",
  currentClass :: Name
currentClass = Name
"",
  _designLog :: Doc
_designLog = Doc
des,
  _loggedSpaces :: [(Space, CodeType)]
_loggedSpaces = [], -- Used to prevent duplicate logs added to design log
  currentScope :: ScopeType
currentScope = ScopeType
Global
}
  where pinfo :: PrintingInformation
pinfo = ChunkDB -> Stage -> Notation -> PrintingInformation
piSys (CodeSpec
cs CodeSpec -> Getting ChunkDB CodeSpec ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB CodeSpec ChunkDB
forall c. HasSystemMeta c => Lens' c ChunkDB
Lens' CodeSpec ChunkDB
systemdb) Stage
Implementation Notation
Scientific
        (MatchedConceptMap
mcm, [Sentence]
concLog) = State [Sentence] MatchedConceptMap
-> [Sentence] -> (MatchedConceptMap, [Sentence])
forall s a. State s a -> s -> (a, s)
runState (Choices -> State [Sentence] MatchedConceptMap
chooseConcept Choices
chs) []
        showDate :: Visibility -> Name
showDate Visibility
Show = Name
dt
        showDate Visibility
Hide = Name
""
        ((Maybe Name
pth, [(Name, ExtLibState)]
elmap, (Name, Name)
lname), [Sentence]
libLog) = State [Sentence] ODEGenInfo
-> [Sentence] -> (ODEGenInfo, [Sentence])
forall s a. State s a -> s -> (a, s)
runState (Lang -> Maybe ODE -> State [Sentence] ODEGenInfo
chooseODELib Lang
l (Maybe ODE -> State [Sentence] ODEGenInfo)
-> Maybe ODE -> State [Sentence] ODEGenInfo
forall a b. (a -> b) -> a -> b
$ [ExtLib] -> Maybe ODE
getODE ([ExtLib] -> Maybe ODE) -> [ExtLib] -> Maybe ODE
forall a b. (a -> b) -> a -> b
$ Choices -> [ExtLib]
extLibs Choices
chs) []
        els :: [ExtLibState]
els = ((Name, ExtLibState) -> ExtLibState)
-> [(Name, ExtLibState)] -> [ExtLibState]
forall a b. (a -> b) -> [a] -> [b]
map (Name, ExtLibState) -> ExtLibState
forall a b. (a, b) -> b
snd [(Name, ExtLibState)]
elmap
        nms :: [(Name, Name)]
nms = [(Name, Name)
lname]
        mem :: ModExportMap
mem = CodeSpec -> Choices -> [Mod] -> ModExportMap
modExportMap CodeSpec
cs Choices
chs [Mod]
modules'
        lem :: ModExportMap
lem = [(Name, Name)] -> ModExportMap
forall k a. Ord k => [(k, a)] -> Map k a
fromList ((ExtLibState -> [(Name, Name)]) -> [ExtLibState] -> [(Name, Name)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ExtLibState
-> Getting [(Name, Name)] ExtLibState [(Name, Name)]
-> [(Name, Name)]
forall s a. s -> Getting a s a -> a
^. Getting [(Name, Name)] ExtLibState [(Name, Name)]
Lens' ExtLibState [(Name, Name)]
modExports) [ExtLibState]
els)
        cdm :: ModExportMap
cdm = CodeSpec -> Choices -> [Mod] -> ModExportMap
clsDefMap CodeSpec
cs Choices
chs [Mod]
modules'
        modules' :: [Mod]
modules' = (CodeSpec
cs CodeSpec -> Getting [Mod] CodeSpec [Mod] -> [Mod]
forall s a. s -> Getting a s a -> a
^. Getting [Mod] CodeSpec [Mod]
forall c. HasCodeSpec c => Lens' c [Mod]
Lens' CodeSpec [Mod]
mods) [Mod] -> [Mod] -> [Mod]
forall a. [a] -> [a] -> [a]
++ (ExtLibState -> [Mod]) -> [ExtLibState] -> [Mod]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ExtLibState -> Getting [Mod] ExtLibState [Mod] -> [Mod]
forall s a. s -> Getting a s a -> a
^. Getting [Mod] ExtLibState [Mod]
Lens' ExtLibState [Mod]
auxMods) [ExtLibState]
els
        nonPrefChs :: [Sentence]
nonPrefChs = Choices -> [Sentence]
choicesSent Choices
chs
        des :: Doc
des = [Doc] -> Doc
vcat ([Doc] -> Doc) -> [Doc] -> Doc
forall a b. (a -> b) -> a -> b
$
          (Sentence -> Doc) -> [Sentence] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo) ([Sentence]
nonPrefChs [Sentence] -> [Sentence] -> [Sentence]
forall a. [a] -> [a] -> [a]
++ [Sentence]
concLog [Sentence] -> [Sentence] -> [Sentence]
forall a. [a] -> [a] -> [a]
++ [Sentence]
libLog)

-- OO Versions --

data SomeProgGenerator where
  SomeProgGenerator
    :: forall repr vis smt md svr att prg. (OOProg repr vis smt md svr att prg)
    => (repr prg -> ProgData) -> SomeProgGenerator

-- | Generates a package with the given 'DrasilState'. The passed
-- un-representation functions determine which target language the package will
-- be generated in.
generateCode :: (SoftwareDossierSym packRepr, Monad packRepr) =>
  Lang -> SomeProgGenerator ->
  (packRepr PackageData -> PackageData) -> DrasilState -> FileLayout
generateCode :: forall (packRepr :: * -> *).
(SoftwareDossierSym packRepr, Monad packRepr) =>
Lang
-> SomeProgGenerator
-> (packRepr PackageData -> PackageData)
-> DrasilState
-> FileLayout
generateCode Lang
l (SomeProgGenerator repr prg -> ProgData
unReprProg) packRepr PackageData -> PackageData
unReprPack DrasilState
g =
  let dirName :: Name
dirName = Lang -> Name
getDir Lang
l
      (packRepr PackageData
pckg, DrasilState
ds) = State DrasilState (packRepr PackageData)
-> DrasilState -> (packRepr PackageData, DrasilState)
forall s a. State s a -> s -> (a, s)
runState ((repr prg -> ProgData) -> State DrasilState (packRepr PackageData)
forall (progRepr :: * -> *) vis smt md svr att prg
       (packRepr :: * -> *).
(OOProg progRepr vis smt md svr att prg,
 SoftwareDossierSym packRepr, Monad packRepr) =>
(progRepr prg -> ProgData) -> GenState (packRepr PackageData)
genPackage repr prg -> ProgData
unReprProg) DrasilState
g
      (PackageData ProgData
prog [FileLayout]
progDossier) = packRepr PackageData -> PackageData
unReprPack packRepr PackageData
pckg
      designLogFile :: [FileLayout]
designLogFile = [PathSegment -> Doc -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
file [ps|designLog.txt|] (DrasilState
ds DrasilState -> Getting Doc DrasilState Doc -> Doc
forall s a. s -> Getting a s a -> a
^. Getting Doc DrasilState Doc
Lens' DrasilState Doc
designLog) |
                        Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Doc -> Bool
isEmpty (Doc -> Bool) -> Doc -> Bool
forall a b. (a -> b) -> a -> b
$ DrasilState
ds DrasilState -> Getting Doc DrasilState Doc -> Doc
forall s a. s -> Getting a s a -> a
^. Getting Doc DrasilState Doc
Lens' DrasilState Doc
designLog]
      initFile :: [FileLayout]
initFile = [PathSegment -> Doc -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
exactFile [ps|__init__.py|] Doc
empty | Lang
l Lang -> Lang -> Bool
forall a. Eq a => a -> a -> Bool
== Lang
Python]
      packageFiles :: [FileLayout]
packageFiles = [FileData] -> [FileLayout]
toFileLayout (ProgData -> [FileData]
progMods ProgData
prog) [FileLayout] -> [FileLayout] -> [FileLayout]
forall a. [a] -> [a] -> [a]
++ [FileLayout]
progDossier
        [FileLayout] -> [FileLayout] -> [FileLayout]
forall a. [a] -> [a] -> [a]
++ [FileLayout]
designLogFile [FileLayout] -> [FileLayout] -> [FileLayout]
forall a. [a] -> [a] -> [a]
++ [FileLayout]
initFile
  in
    PathSegment -> [FileLayout] -> FileLayout
forall (f :: * -> *).
Foldable f =>
PathSegment -> f FileLayout -> FileLayout
directory
      [ps|{dirName}|]
      [FileLayout]
packageFiles

-- | Internal: Converts a list of `FileData` to a `FileLayout`.
toFileLayout :: [FileData] -> [FileLayout]
toFileLayout :: [FileData] -> [FileLayout]
toFileLayout [FileData]
fc =
  let
    root :: Map Name (Entry Doc)
root = (Map Name (Entry Doc) -> FileData -> Map Name (Entry Doc))
-> Map Name (Entry Doc) -> [FileData] -> Map Name (Entry Doc)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Map Name (Entry Doc)
m FileData
f -> (Name, Doc) -> Map Name (Entry Doc) -> Map Name (Entry Doc)
forall a. (Name, a) -> Map Name (Entry a) -> Map Name (Entry a)
insertFile (FileData -> Name
filePath FileData
f, ModData -> Doc
modDoc (ModData -> Doc) -> ModData -> Doc
forall a b. (a -> b) -> a -> b
$ FileData -> ModData
fileMod FileData
f) Map Name (Entry Doc)
m) Map Name (Entry Doc)
forall k a. Map k a
M.empty [FileData]
fc

    entryToLayout :: (Name, Entry doc) -> FileLayout
entryToLayout (Name
n, File doc
d) = PathSegment -> doc -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
file [ps|{n}|] doc
d
    entryToLayout (Name
n, Folder Map Name (Entry doc)
m) = PathSegment -> [FileLayout] -> FileLayout
forall (f :: * -> *).
Foldable f =>
PathSegment -> f FileLayout -> FileLayout
directory [ps|{n}|] ([FileLayout] -> FileLayout) -> [FileLayout] -> FileLayout
forall a b. (a -> b) -> a -> b
$ ((Name, Entry doc) -> FileLayout)
-> [(Name, Entry doc)] -> [FileLayout]
forall a b. (a -> b) -> [a] -> [b]
map (Name, Entry doc) -> FileLayout
entryToLayout ([(Name, Entry doc)] -> [FileLayout])
-> [(Name, Entry doc)] -> [FileLayout]
forall a b. (a -> b) -> a -> b
$ Map Name (Entry doc) -> [(Name, Entry doc)]
forall k a. Map k a -> [(k, a)]
M.assocs Map Name (Entry doc)
m
  in
    ((Name, Entry Doc) -> FileLayout)
-> [(Name, Entry Doc)] -> [FileLayout]
forall a b. (a -> b) -> [a] -> [b]
map (Name, Entry Doc) -> FileLayout
forall {doc}. Writeable doc => (Name, Entry doc) -> FileLayout
entryToLayout (Map Name (Entry Doc) -> [(Name, Entry Doc)]
forall k a. Map k a -> [(k, a)]
M.assocs Map Name (Entry Doc)
root)

data Entry a = File a | Folder (M.Map String (Entry a))
  deriving (Int -> Entry a -> ShowS
[Entry a] -> ShowS
Entry a -> Name
(Int -> Entry a -> ShowS)
-> (Entry a -> Name) -> ([Entry a] -> ShowS) -> Show (Entry a)
forall a. Show a => Int -> Entry a -> ShowS
forall a. Show a => [Entry a] -> ShowS
forall a. Show a => Entry a -> Name
forall a.
(Int -> a -> ShowS) -> (a -> Name) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Entry a -> ShowS
showsPrec :: Int -> Entry a -> ShowS
$cshow :: forall a. Show a => Entry a -> Name
show :: Entry a -> Name
$cshowList :: forall a. Show a => [Entry a] -> ShowS
showList :: [Entry a] -> ShowS
Show)

insertFile :: (String, a) -> M.Map String (Entry a) -> M.Map String (Entry a)
insertFile :: forall a. (Name, a) -> Map Name (Entry a) -> Map Name (Entry a)
insertFile (Name
p, a
d) Map Name (Entry a)
m =
  if Char
'/' Char -> Name -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Name
p
    then
      let (Name
fname, Name
rest) = (Char -> Bool) -> Name -> (Name, Name)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'/') Name
p
          folderM :: Map Name (Entry a)
folderM = case Entry a -> Name -> Map Name (Entry a) -> Entry a
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault (Map Name (Entry a) -> Entry a
forall a. Map Name (Entry a) -> Entry a
Folder Map Name (Entry a)
forall k a. Map k a
M.empty) Name
fname Map Name (Entry a)
m of
                      File a
_   -> Name -> Map Name (Entry a)
forall {a}. Name -> a
dupError Name
fname
                      Folder Map Name (Entry a)
f -> Map Name (Entry a)
f
      in Name -> Entry a -> Map Name (Entry a) -> Map Name (Entry a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Name
fname (Map Name (Entry a) -> Entry a
forall a. Map Name (Entry a) -> Entry a
Folder (Map Name (Entry a) -> Entry a) -> Map Name (Entry a) -> Entry a
forall a b. (a -> b) -> a -> b
$ (Name, a) -> Map Name (Entry a) -> Map Name (Entry a)
forall a. (Name, a) -> Map Name (Entry a) -> Map Name (Entry a)
insertFile (Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
1 Name
rest, a
d) Map Name (Entry a)
folderM) Map Name (Entry a)
m
    else (Entry a -> Entry a -> Entry a)
-> Name -> Entry a -> Map Name (Entry a) -> Map Name (Entry a)
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith (\Entry a
_ -> Name -> Entry a -> Entry a
forall {a}. Name -> a
dupError Name
p) Name
p (a -> Entry a
forall a. a -> Entry a
File a
d) Map Name (Entry a)
m
  where
    dupError :: Name -> a
dupError Name
fname = Name -> a
forall a. HasCallStack => Name -> a
error (Name -> a) -> Name -> a
forall a b. (a -> b) -> a -> b
$ Name
"A file or folder with name '" Name -> ShowS
forall a. [a] -> [a] -> [a]
++ Name
fname Name -> ShowS
forall a. [a] -> [a] -> [a]
++ Name
"' already exists."

-- | Generates a package, including a Makefile, sample input file, and Doxygen
-- configuration file (all subject to the user's choices).
-- The passed un-representation function determines which target language the
-- package will be generated in.
-- GOOL's static code analysis interpreter is called to initialize the state
-- used by the language renderer.
genPackage
  :: (OOProg progRepr vis smt md svr att prg, SoftwareDossierSym packRepr, Monad packRepr)
  => (progRepr prg -> ProgData)
  -> GenState (packRepr PackageData)
genPackage :: forall (progRepr :: * -> *) vis smt md svr att prg
       (packRepr :: * -> *).
(OOProg progRepr vis smt md svr att prg,
 SoftwareDossierSym packRepr, Monad packRepr) =>
(progRepr prg -> ProgData) -> GenState (packRepr PackageData)
genPackage progRepr prg -> ProgData
unRepr = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  GSProgram CodeInfoOO GOOLState
ci <- GenState (GSProgram CodeInfoOO GOOLState)
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (GSProgram r prg)
genProgram
  GSProgram progRepr prg
p <- GenState (GSProgram progRepr prg)
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (GSProgram r prg)
genProgram
  let info :: GOOLState
info = CodeInfoOO GOOLState -> GOOLState
forall a. CodeInfoOO a -> a
OO.unCI (CodeInfoOO GOOLState -> GOOLState)
-> CodeInfoOO GOOLState -> GOOLState
forall a b. (a -> b) -> a -> b
$ GSProgram CodeInfoOO GOOLState -> GOOLState -> CodeInfoOO GOOLState
forall s a. State s a -> s -> a
evalState GSProgram CodeInfoOO GOOLState
ci GOOLState
initialState
      (progRepr prg
reprPD, GOOLState
s) = GSProgram progRepr prg -> GOOLState -> (progRepr prg, GOOLState)
forall s a. State s a -> s -> (a, s)
runState GSProgram progRepr prg
p GOOLState
info
      fileInfoState :: SoftwareDossierState
fileInfoState = [Name] -> [Name] -> Maybe Name -> SoftwareDossierState
makeSds (GOOLState
s GOOLState -> Getting [Name] GOOLState [Name] -> [Name]
forall s a. s -> Getting a s a -> a
^. Getting [Name] GOOLState [Name]
Lens' GOOLState [Name]
headers) (GOOLState
s GOOLState -> Getting [Name] GOOLState [Name] -> [Name]
forall s a. s -> Getting a s a -> a
^. Getting [Name] GOOLState [Name]
Lens' GOOLState [Name]
sources) (GOOLState
s GOOLState
-> Getting (Maybe Name) GOOLState (Maybe Name) -> Maybe Name
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Name) GOOLState (Maybe Name)
Lens' GOOLState (Maybe Name)
mainMod)
      pd :: ProgData
pd = progRepr prg -> ProgData
unRepr progRepr prg
reprPD
      m :: packRepr FileLayout
m = [Name]
-> ImplementationType
-> [Comments]
-> SoftwareDossierState
-> ProgData
-> packRepr FileLayout
forall (r :: * -> *).
SoftwareDossierSym r =>
[Name]
-> ImplementationType
-> [Comments]
-> SoftwareDossierState
-> ProgData
-> r FileLayout
makefile (DrasilState -> [Name]
libPaths DrasilState
g) (DrasilState
g DrasilState
-> Getting ImplementationType DrasilState ImplementationType
-> ImplementationType
forall s a. s -> Getting a s a -> a
^. Getting ImplementationType DrasilState ImplementationType
forall a. HasChoices a => Lens' a ImplementationType
Lens' DrasilState ImplementationType
implType) (DrasilState
g DrasilState
-> Getting [Comments] DrasilState [Comments] -> [Comments]
forall s a. s -> Getting a s a -> a
^. Getting [Comments] DrasilState [Comments]
forall a. HasChoices a => Lens' a [Comments]
Lens' DrasilState [Comments]
commented) SoftwareDossierState
fileInfoState ProgData
pd
      as :: [Name]
as = (Person -> Name) -> [Person] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map Person -> Name
forall n. HasName n => n -> Name
fullName (DrasilState
g DrasilState -> Getting [Person] DrasilState [Person] -> [Person]
forall s a. s -> Getting a s a -> a
^. Getting [Person] DrasilState [Person]
forall c. HasSystemMeta c => Lens' c [Person]
Lens' DrasilState [Person]
authors)
      cfp :: [RelativeFile]
cfp = DrasilState
g DrasilState
-> Getting [RelativeFile] DrasilState [RelativeFile]
-> [RelativeFile]
forall s a. s -> Getting a s a -> a
^. Getting [RelativeFile] DrasilState [RelativeFile]
forall c. HasCodeSpec c => Lens' c [RelativeFile]
Lens' DrasilState [RelativeFile]
configFiles
      pinfo :: PrintingInformation
pinfo = DrasilState -> PrintingInformation
printfo DrasilState
g
      -- FIXME: The below code does `Doc -> String` conversion.
      prps :: Name
prps = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
purpose)
      bckgrnd :: Name
bckgrnd = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
background)
      mtvtn :: Name
mtvtn = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
motivation)
      scp :: Name
scp = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
scope)
  Maybe (packRepr FileLayout)
i <- GenState (Maybe (packRepr FileLayout))
forall (r :: * -> *).
Applicative r =>
GenState (Maybe (r FileLayout))
genSampleInput
  Maybe (packRepr FileLayout)
d <- SoftwareDossierState -> GenState (Maybe (packRepr FileLayout))
forall (r :: * -> *).
SoftwareDossierSym r =>
SoftwareDossierState -> GenState (Maybe (r FileLayout))
genDoxConfig SoftwareDossierState
fileInfoState
  Maybe (packRepr FileLayout)
rm <- ReadMeInfo -> GenState (Maybe (packRepr FileLayout))
forall (r :: * -> *).
SoftwareDossierSym r =>
ReadMeInfo -> GenState (Maybe (r FileLayout))
genReadMe ReadMeInfo {
        langName :: Name
langName = Name
"",
        langVersion :: Name
langVersion = Name
"",
        invalidOS :: Maybe Name
invalidOS = Maybe Name
forall a. Maybe a
Nothing,
        implementType :: ImplementationType
implementType = DrasilState
g DrasilState
-> Getting ImplementationType DrasilState ImplementationType
-> ImplementationType
forall s a. s -> Getting a s a -> a
^. Getting ImplementationType DrasilState ImplementationType
forall a. HasChoices a => Lens' a ImplementationType
Lens' DrasilState ImplementationType
implType,
        extLibNV :: [(Name, Name)]
extLibNV = DrasilState -> [(Name, Name)]
extLibNames DrasilState
g,
        extLibFP :: [Name]
extLibFP = DrasilState -> [Name]
libPaths DrasilState
g,
        contributors :: [Name]
contributors = [Name]
as,
        configFP :: [RelativeFile]
configFP = [RelativeFile]
cfp,
        caseName :: Name
caseName = Name
"",
        examplePurpose :: Name
examplePurpose = Name
prps,
        exampleDescr :: Name
exampleDescr = Name
bckgrnd,
        exampleMotivation :: Name
exampleMotivation = Name
mtvtn,
        exampleScope :: Name
exampleScope = Name
scp,
        folderNum :: Int
folderNum = DrasilState -> Int
getVal DrasilState
g,
        inputOutput :: (Name, Name)
inputOutput = (Name
sampleInputName, Name
"output.txt")} -- This needs a more permanent solution
  packRepr PackageData -> GenState (packRepr PackageData)
forall a. a -> StateT DrasilState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (packRepr PackageData -> GenState (packRepr PackageData))
-> packRepr PackageData -> GenState (packRepr PackageData)
forall a b. (a -> b) -> a -> b
$ ProgData -> [packRepr FileLayout] -> packRepr PackageData
forall (r :: * -> *).
Monad r =>
ProgData -> [r FileLayout] -> r PackageData
package ProgData
pd (packRepr FileLayout
mpackRepr FileLayout
-> [packRepr FileLayout] -> [packRepr FileLayout]
forall a. a -> [a] -> [a]
:[Maybe (packRepr FileLayout)] -> [packRepr FileLayout]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (packRepr FileLayout)
i,Maybe (packRepr FileLayout)
rm,Maybe (packRepr FileLayout)
d])

-- | Generates an SCS program based on the problem and the user's design choices.
genProgram :: (OOProg r vis smt md svr att prg) => GenState (OO.GSProgram r prg)
genProgram :: forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (GSProgram r prg)
genProgram = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  [FS (r FileData)]
ms <- Modularity -> GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
Modularity -> GenState [FS (r FileData)]
chooseModules (Modularity -> GenState [FS (r FileData)])
-> Modularity -> GenState [FS (r FileData)]
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting Modularity DrasilState Modularity -> Modularity
forall s a. s -> Getting a s a -> a
^. Getting Modularity DrasilState Modularity
forall a. HasChoices a => Lens' a Modularity
Lens' DrasilState Modularity
modular
  let n :: Name
n = DrasilState
g DrasilState -> Getting Name DrasilState Name -> Name
forall s a. s -> Getting a s a -> a
^. Getting Name DrasilState Name
forall c. HasSmithEtAlSRS c => Lens' c Name
Lens' DrasilState Name
programName
  -- FIXME: The below code does `Doc -> String` conversion!
  let p :: Name
p = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc (DrasilState -> PrintingInformation
printfo DrasilState
g) (Sentence -> Doc) -> Sentence -> Doc
forall a b. (a -> b) -> a -> b
$ [Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
purpose
  GSProgram r prg -> GenState (GSProgram r prg)
forall a. a -> StateT DrasilState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (GSProgram r prg -> GenState (GSProgram r prg))
-> GSProgram r prg -> GenState (GSProgram r prg)
forall a b. (a -> b) -> a -> b
$ Name -> Name -> [FS (r FileData)] -> GSProgram r prg
forall (r :: * -> *) vis smt md svr att prg.
ProgramSym r vis smt md svr att prg =>
Name -> Name -> [FS (r FileData)] -> GSProgram r prg
OO.prog Name
n Name
p [FS (r FileData)]
ms

-- | Generates either a single module or many modules, based on the users choice
-- of modularity.
chooseModules :: (OOProg r vis smt md svr att prg) => Modularity -> GenState [FS (r File)]
chooseModules :: forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
Modularity -> GenState [FS (r FileData)]
chooseModules Modularity
Unmodular = State DrasilState (FS (r FileData))
-> State DrasilState [FS (r FileData)]
forall a b. State a b -> State a [b]
liftS State DrasilState (FS (r FileData))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (FS (r FileData))
genUnmodular
chooseModules Modularity
Modular = State DrasilState [FS (r FileData)]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState [FS (r FileData)]
genModules

-- | Generates an entire SCS program as a single module.
genUnmodular :: (OOProg r vis smt md svr att prg) => GenState (FS (r File))
genUnmodular :: forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (FS (r FileData))
genUnmodular = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  Name
umDesc <- GenState Name
unmodularDesc
  Name
giName <- InternalConcept -> GenState Name
genICName InternalConcept
GetInput
  Name
dvName <- InternalConcept -> GenState Name
genICName InternalConcept
DerivedValuesFn
  Name
icName <- InternalConcept -> GenState Name
genICName InternalConcept
InputConstraintsFn
  let n :: Name
n = DrasilState
g DrasilState -> Getting Name DrasilState Name -> Name
forall s a. s -> Getting a s a -> a
^. Getting Name DrasilState Name
forall c. HasSmithEtAlSRS c => Lens' c Name
Lens' DrasilState Name
programName
      cls :: Bool
cls = (Name -> Bool) -> [Name] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Name -> ModExportMap -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`member` DrasilState -> ModExportMap
clsMap DrasilState
g) [Name
giName, Name
dvName, Name
icName]
  Name
-> Name
-> [Name]
-> [GenState (Maybe (MS (r md)))]
-> [GenState (Maybe (CS (r Doc)))]
-> GenState (FS (r FileData))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
Name
-> Name
-> [Name]
-> [GenState (Maybe (MS (r md)))]
-> [GenState (Maybe (CS (r Doc)))]
-> GenState (FS (r FileData))
genModuleWithImports Name
n Name
umDesc ((ExtLibState -> [Name]) -> [ExtLibState] -> [Name]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ExtLibState -> Getting [Name] ExtLibState [Name] -> [Name]
forall s a. s -> Getting a s a -> a
^. Getting [Name] ExtLibState [Name]
Lens' ExtLibState [Name]
imports) (ExtLibMap -> [ExtLibState]
forall k a. Map k a -> [a]
elems (ExtLibMap -> [ExtLibState]) -> ExtLibMap -> [ExtLibState]
forall a b. (a -> b) -> a -> b
$ DrasilState -> ExtLibMap
extLibMap DrasilState
g))
    (GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (Maybe (MS (r md)))
genMainFunc
      GenState (Maybe (MS (r md)))
-> [GenState (Maybe (MS (r md)))] -> [GenState (Maybe (MS (r md)))]
forall a. a -> [a] -> [a]
: (StateT DrasilState Identity (MS (r md))
 -> GenState (Maybe (MS (r md))))
-> [StateT DrasilState Identity (MS (r md))]
-> [GenState (Maybe (MS (r md)))]
forall a b. (a -> b) -> [a] -> [b]
map ((MS (r md) -> Maybe (MS (r md)))
-> StateT DrasilState Identity (MS (r md))
-> GenState (Maybe (MS (r md)))
forall a b.
(a -> b)
-> StateT DrasilState Identity a -> StateT DrasilState Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MS (r md) -> Maybe (MS (r md))
forall a. a -> Maybe a
Just) ((CodeDefinition -> StateT DrasilState Identity (MS (r md)))
-> [CodeDefinition] -> [StateT DrasilState Identity (MS (r md))]
forall a b. (a -> b) -> [a] -> [b]
map CodeDefinition -> StateT DrasilState Identity (MS (r md))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
CodeDefinition -> GenState (MS (r md))
genCalcFunc (DrasilState
g DrasilState
-> Getting [CodeDefinition] DrasilState [CodeDefinition]
-> [CodeDefinition]
forall s a. s -> Getting a s a -> a
^. Getting [CodeDefinition] DrasilState [CodeDefinition]
forall c. HasCodeSpec c => Lens' c [CodeDefinition]
Lens' DrasilState [CodeDefinition]
execOrder)
        [StateT DrasilState Identity (MS (r md))]
-> [StateT DrasilState Identity (MS (r md))]
-> [StateT DrasilState Identity (MS (r md))]
forall a. [a] -> [a] -> [a]
++ (Mod -> [StateT DrasilState Identity (MS (r md))])
-> [Mod] -> [StateT DrasilState Identity (MS (r md))]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Mod -> [StateT DrasilState Identity (MS (r md))]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
Mod -> [GenState (MS (r md))]
genModFuncs (DrasilState -> [Mod]
modules DrasilState
g))
      [GenState (Maybe (MS (r md)))]
-> [GenState (Maybe (MS (r md)))] -> [GenState (Maybe (MS (r md)))]
forall a. [a] -> [a] -> [a]
++ ((if Bool
cls then [] else [VisibilityTag -> GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
VisibilityTag -> GenState (Maybe (MS (r md)))
genInputFormat VisibilityTag
Pub, VisibilityTag -> GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
VisibilityTag -> GenState (Maybe (MS (r md)))
genInputDerived VisibilityTag
Pub,
        VisibilityTag -> GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
VisibilityTag -> GenState (Maybe (MS (r md)))
genInputConstraints VisibilityTag
Pub]) [GenState (Maybe (MS (r md)))]
-> [GenState (Maybe (MS (r md)))] -> [GenState (Maybe (MS (r md)))]
forall a. [a] -> [a] -> [a]
++ [GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (Maybe (MS (r md)))
genOutputFormat]))
    ([ClassType -> GenState (Maybe (CS (r Doc)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
ClassType -> GenState (Maybe (CS (r Doc)))
genInputClass ClassType
Auxiliary, ClassType -> GenState (Maybe (CS (r Doc)))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
ClassType -> GenState (Maybe (CS (r Doc)))
genConstClass ClassType
Auxiliary]
      [GenState (Maybe (CS (r Doc)))]
-> [GenState (Maybe (CS (r Doc)))]
-> [GenState (Maybe (CS (r Doc)))]
forall a. [a] -> [a] -> [a]
++ (StateT DrasilState Identity (CS (r Doc))
 -> GenState (Maybe (CS (r Doc))))
-> [StateT DrasilState Identity (CS (r Doc))]
-> [GenState (Maybe (CS (r Doc)))]
forall a b. (a -> b) -> [a] -> [b]
map ((CS (r Doc) -> Maybe (CS (r Doc)))
-> StateT DrasilState Identity (CS (r Doc))
-> GenState (Maybe (CS (r Doc)))
forall a b.
(a -> b)
-> StateT DrasilState Identity a -> StateT DrasilState Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CS (r Doc) -> Maybe (CS (r Doc))
forall a. a -> Maybe a
Just) ((Mod -> [StateT DrasilState Identity (CS (r Doc))])
-> [Mod] -> [StateT DrasilState Identity (CS (r Doc))]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Mod -> [StateT DrasilState Identity (CS (r Doc))]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
Mod -> [GenState (CS (r Doc))]
genModClasses ([Mod] -> [StateT DrasilState Identity (CS (r Doc))])
-> [Mod] -> [StateT DrasilState Identity (CS (r Doc))]
forall a b. (a -> b) -> a -> b
$ DrasilState -> [Mod]
modules DrasilState
g))

-- | Generates all modules for an SCS program.
genModules :: (OOProg r vis smt md svr att prg) => GenState [FS (r File)]
genModules :: forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState [FS (r FileData)]
genModules = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  FS (r FileData)
mn     <- GenState (FS (r FileData))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (FS (r FileData))
genMain
  [FS (r FileData)]
inp    <- GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState [FS (r FileData)]
genInputMod
  [FS (r FileData)]
con    <- GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState [FS (r FileData)]
genConstMod
  FS (r FileData)
cal    <- GenState (FS (r FileData))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState (FS (r FileData))
genCalcMod
  [FS (r FileData)]
out    <- GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
GenState [FS (r FileData)]
genOutputMod
  [FS (r FileData)]
moddef <- (Mod -> GenState (FS (r FileData)))
-> [Mod] -> GenState [FS (r FileData)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Mod -> GenState (FS (r FileData))
forall (r :: * -> *) vis smt md svr att prg.
OOProg r vis smt md svr att prg =>
Mod -> GenState (FS (r FileData))
genModDef (DrasilState -> [Mod]
modules DrasilState
g) -- hack ?
  [FS (r FileData)] -> GenState [FS (r FileData)]
forall a. a -> StateT DrasilState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ([FS (r FileData)] -> GenState [FS (r FileData)])
-> [FS (r FileData)] -> GenState [FS (r FileData)]
forall a b. (a -> b) -> a -> b
$ FS (r FileData)
mn FS (r FileData) -> [FS (r FileData)] -> [FS (r FileData)]
forall a. a -> [a] -> [a]
: [FS (r FileData)]
inp [FS (r FileData)] -> [FS (r FileData)] -> [FS (r FileData)]
forall a. [a] -> [a] -> [a]
++ [FS (r FileData)]
con [FS (r FileData)] -> [FS (r FileData)] -> [FS (r FileData)]
forall a. [a] -> [a] -> [a]
++ FS (r FileData)
cal FS (r FileData) -> [FS (r FileData)] -> [FS (r FileData)]
forall a. a -> [a] -> [a]
: [FS (r FileData)]
out [FS (r FileData)] -> [FS (r FileData)] -> [FS (r FileData)]
forall a. [a] -> [a] -> [a]
++ [FS (r FileData)]
moddef

-- Procedural Versions --

-- | Generates a package with the given 'DrasilState'. The passed
-- un-representation functions determine which target language the package will
-- be generated in.
generateCodeProc
  :: (ProcProg progRepr vis smt md prg, NativeVector progRepr, SoftwareDossierSym packRepr, Monad packRepr)
  => Lang
  -> (progRepr prg -> ProgData)
  -> (packRepr PackageData -> PackageData)
  -> DrasilState
  -> FileLayout
generateCodeProc :: forall (progRepr :: * -> *) vis smt md prg (packRepr :: * -> *).
(ProcProg progRepr vis smt md prg, NativeVector progRepr,
 SoftwareDossierSym packRepr, Monad packRepr) =>
Lang
-> (progRepr prg -> ProgData)
-> (packRepr PackageData -> PackageData)
-> DrasilState
-> FileLayout
generateCodeProc Lang
l progRepr prg -> ProgData
unReprProg packRepr PackageData -> PackageData
unReprPack DrasilState
g =
  let dirName :: Name
dirName = Lang -> Name
getDir Lang
l
      (packRepr PackageData
pckg, DrasilState
ds) = State DrasilState (packRepr PackageData)
-> DrasilState -> (packRepr PackageData, DrasilState)
forall s a. State s a -> s -> (a, s)
runState ((progRepr prg -> ProgData)
-> State DrasilState (packRepr PackageData)
forall (progRepr :: * -> *) vis smt md prg (packRepr :: * -> *).
(ProcProg progRepr vis smt md prg, NativeVector progRepr,
 SoftwareDossierSym packRepr, Monad packRepr) =>
(progRepr prg -> ProgData) -> GenState (packRepr PackageData)
genPackageProc progRepr prg -> ProgData
unReprProg) DrasilState
g
      (PackageData ProgData
prog [FileLayout]
progDossier) = packRepr PackageData -> PackageData
unReprPack packRepr PackageData
pckg
      designLogFile :: [FileLayout]
designLogFile = [PathSegment -> Doc -> FileLayout
forall doc. Writeable doc => PathSegment -> doc -> FileLayout
file [ps|designLog.txt|] (DrasilState
ds DrasilState -> Getting Doc DrasilState Doc -> Doc
forall s a. s -> Getting a s a -> a
^. Getting Doc DrasilState Doc
Lens' DrasilState Doc
designLog) |
                        Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Doc -> Bool
isEmpty (Doc -> Bool) -> Doc -> Bool
forall a b. (a -> b) -> a -> b
$ DrasilState
ds DrasilState -> Getting Doc DrasilState Doc -> Doc
forall s a. s -> Getting a s a -> a
^. Getting Doc DrasilState Doc
Lens' DrasilState Doc
designLog]
      packageFiles :: [FileLayout]
packageFiles = [FileData] -> [FileLayout]
toFileLayout (ProgData -> [FileData]
progMods ProgData
prog) [FileLayout] -> [FileLayout] -> [FileLayout]
forall a. [a] -> [a] -> [a]
++ [FileLayout]
progDossier
        [FileLayout] -> [FileLayout] -> [FileLayout]
forall a. [a] -> [a] -> [a]
++ [FileLayout]
designLogFile
  in
    PathSegment -> [FileLayout] -> FileLayout
forall (f :: * -> *).
Foldable f =>
PathSegment -> f FileLayout -> FileLayout
directory
      [ps|{dirName}|]
      [FileLayout]
packageFiles

-- | Generates a package, including a Makefile, sample input file, and Doxygen
-- configuration file (all subject to the user's choices).
-- The passed un-representation function determines which target language the
-- package will be generated in.
-- GOOL's static code analysis interpreter is called to initialize the state
-- used by the language renderer.
genPackageProc
  :: (ProcProg progRepr vis smt md prg, NativeVector progRepr, SoftwareDossierSym packRepr, Monad packRepr)
  => (progRepr prg -> ProgData)
  -> GenState (packRepr PackageData)
genPackageProc :: forall (progRepr :: * -> *) vis smt md prg (packRepr :: * -> *).
(ProcProg progRepr vis smt md prg, NativeVector progRepr,
 SoftwareDossierSym packRepr, Monad packRepr) =>
(progRepr prg -> ProgData) -> GenState (packRepr PackageData)
genPackageProc progRepr prg -> ProgData
unRepr = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  GSProgram progRepr prg
p <- GenState (GSProgram progRepr prg)
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState (GSProgram r prg)
genProgramProc
  let (progRepr prg
reprPD, GOOLState
s) = GSProgram progRepr prg -> GOOLState -> (progRepr prg, GOOLState)
forall s a. State s a -> s -> (a, s)
runState GSProgram progRepr prg
p GOOLState
initialState
      fileInfoState :: SoftwareDossierState
fileInfoState = [Name] -> [Name] -> Maybe Name -> SoftwareDossierState
makeSds (GOOLState
s GOOLState -> Getting [Name] GOOLState [Name] -> [Name]
forall s a. s -> Getting a s a -> a
^. Getting [Name] GOOLState [Name]
Lens' GOOLState [Name]
headers) (GOOLState
s GOOLState -> Getting [Name] GOOLState [Name] -> [Name]
forall s a. s -> Getting a s a -> a
^. Getting [Name] GOOLState [Name]
Lens' GOOLState [Name]
sources) (GOOLState
s GOOLState
-> Getting (Maybe Name) GOOLState (Maybe Name) -> Maybe Name
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Name) GOOLState (Maybe Name)
Lens' GOOLState (Maybe Name)
mainMod)
      pd :: ProgData
pd = progRepr prg -> ProgData
unRepr progRepr prg
reprPD
      m :: packRepr FileLayout
m = [Name]
-> ImplementationType
-> [Comments]
-> SoftwareDossierState
-> ProgData
-> packRepr FileLayout
forall (r :: * -> *).
SoftwareDossierSym r =>
[Name]
-> ImplementationType
-> [Comments]
-> SoftwareDossierState
-> ProgData
-> r FileLayout
makefile (DrasilState -> [Name]
libPaths DrasilState
g) (DrasilState
g DrasilState
-> Getting ImplementationType DrasilState ImplementationType
-> ImplementationType
forall s a. s -> Getting a s a -> a
^. Getting ImplementationType DrasilState ImplementationType
forall a. HasChoices a => Lens' a ImplementationType
Lens' DrasilState ImplementationType
implType) (DrasilState
g DrasilState
-> Getting [Comments] DrasilState [Comments] -> [Comments]
forall s a. s -> Getting a s a -> a
^. Getting [Comments] DrasilState [Comments]
forall a. HasChoices a => Lens' a [Comments]
Lens' DrasilState [Comments]
commented) SoftwareDossierState
fileInfoState ProgData
pd
      as :: [Name]
as = (Person -> Name) -> [Person] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map Person -> Name
forall n. HasName n => n -> Name
fullName (DrasilState
g DrasilState -> Getting [Person] DrasilState [Person] -> [Person]
forall s a. s -> Getting a s a -> a
^. Getting [Person] DrasilState [Person]
forall c. HasSystemMeta c => Lens' c [Person]
Lens' DrasilState [Person]
authors)
      cfp :: [RelativeFile]
cfp = DrasilState
g DrasilState
-> Getting [RelativeFile] DrasilState [RelativeFile]
-> [RelativeFile]
forall s a. s -> Getting a s a -> a
^. Getting [RelativeFile] DrasilState [RelativeFile]
forall c. HasCodeSpec c => Lens' c [RelativeFile]
Lens' DrasilState [RelativeFile]
configFiles
      pinfo :: PrintingInformation
pinfo = DrasilState -> PrintingInformation
printfo DrasilState
g
      prps :: Name
prps = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
purpose)
      bckgrnd :: Name
bckgrnd = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
background)
      mtvtn :: Name
mtvtn = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
motivation)
      scp :: Name
scp = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc PrintingInformation
pinfo ([Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
scope)
  Maybe (packRepr FileLayout)
i <- GenState (Maybe (packRepr FileLayout))
forall (r :: * -> *).
Applicative r =>
GenState (Maybe (r FileLayout))
genSampleInput
  Maybe (packRepr FileLayout)
d <- SoftwareDossierState -> GenState (Maybe (packRepr FileLayout))
forall (r :: * -> *).
SoftwareDossierSym r =>
SoftwareDossierState -> GenState (Maybe (r FileLayout))
genDoxConfig SoftwareDossierState
fileInfoState
  Maybe (packRepr FileLayout)
rm <- ReadMeInfo -> GenState (Maybe (packRepr FileLayout))
forall (r :: * -> *).
SoftwareDossierSym r =>
ReadMeInfo -> GenState (Maybe (r FileLayout))
genReadMe ReadMeInfo {
        langName :: Name
langName = Name
"",
        langVersion :: Name
langVersion = Name
"",
        invalidOS :: Maybe Name
invalidOS = Maybe Name
forall a. Maybe a
Nothing,
        implementType :: ImplementationType
implementType = DrasilState
g DrasilState
-> Getting ImplementationType DrasilState ImplementationType
-> ImplementationType
forall s a. s -> Getting a s a -> a
^. Getting ImplementationType DrasilState ImplementationType
forall a. HasChoices a => Lens' a ImplementationType
Lens' DrasilState ImplementationType
implType,
        extLibNV :: [(Name, Name)]
extLibNV = DrasilState -> [(Name, Name)]
extLibNames DrasilState
g,
        extLibFP :: [Name]
extLibFP = DrasilState -> [Name]
libPaths DrasilState
g,
        contributors :: [Name]
contributors = [Name]
as,
        configFP :: [RelativeFile]
configFP = [RelativeFile]
cfp,
        caseName :: Name
caseName = Name
"",
        examplePurpose :: Name
examplePurpose = Name
prps,
        exampleDescr :: Name
exampleDescr = Name
bckgrnd,
        exampleMotivation :: Name
exampleMotivation = Name
mtvtn,
        exampleScope :: Name
exampleScope = Name
scp,
        folderNum :: Int
folderNum = DrasilState -> Int
getVal DrasilState
g,
        inputOutput :: (Name, Name)
inputOutput = (Name
sampleInputName, Name
"output.txt")} -- This needs a more permanent solution
  packRepr PackageData -> GenState (packRepr PackageData)
forall a. a -> StateT DrasilState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (packRepr PackageData -> GenState (packRepr PackageData))
-> packRepr PackageData -> GenState (packRepr PackageData)
forall a b. (a -> b) -> a -> b
$ ProgData -> [packRepr FileLayout] -> packRepr PackageData
forall (r :: * -> *).
Monad r =>
ProgData -> [r FileLayout] -> r PackageData
package ProgData
pd (packRepr FileLayout
mpackRepr FileLayout
-> [packRepr FileLayout] -> [packRepr FileLayout]
forall a. a -> [a] -> [a]
:[Maybe (packRepr FileLayout)] -> [packRepr FileLayout]
forall a. [Maybe a] -> [a]
catMaybes [Maybe (packRepr FileLayout)
i,Maybe (packRepr FileLayout)
rm,Maybe (packRepr FileLayout)
d])

-- | Generates an SCS program based on the problem and the user's design choices.
genProgramProc
  :: (ProcProg r vis smt md prg, NativeVector r)
  => GenState (Proc.GSProgram r prg)
genProgramProc :: forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState (GSProgram r prg)
genProgramProc = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  [FS (r FileData)]
ms <- Modularity -> GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
Modularity -> GenState [FS (r FileData)]
chooseModulesProc (Modularity -> GenState [FS (r FileData)])
-> Modularity -> GenState [FS (r FileData)]
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting Modularity DrasilState Modularity -> Modularity
forall s a. s -> Getting a s a -> a
^. Getting Modularity DrasilState Modularity
forall a. HasChoices a => Lens' a Modularity
Lens' DrasilState Modularity
modular
  let n :: Name
n = DrasilState
g DrasilState -> Getting Name DrasilState Name -> Name
forall s a. s -> Getting a s a -> a
^. Getting Name DrasilState Name
forall c. HasSmithEtAlSRS c => Lens' c Name
Lens' DrasilState Name
programName
  let p :: Name
p = Doc -> Name
forall a. Show a => a -> Name
show (Doc -> Name) -> Doc -> Name
forall a b. (a -> b) -> a -> b
$ PrintingInformation -> Sentence -> Doc
oneLineSentenceDoc (DrasilState -> PrintingInformation
printfo DrasilState
g) (Sentence -> Doc) -> Sentence -> Doc
forall a b. (a -> b) -> a -> b
$ [Sentence] -> Sentence
foldlSent ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ DrasilState
g DrasilState
-> Getting [Sentence] DrasilState [Sentence] -> [Sentence]
forall s a. s -> Getting a s a -> a
^. Getting [Sentence] DrasilState [Sentence]
forall c. HasSystemMeta c => Lens' c [Sentence]
Lens' DrasilState [Sentence]
purpose
  GSProgram r prg -> GenState (GSProgram r prg)
forall a. a -> StateT DrasilState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (GSProgram r prg -> GenState (GSProgram r prg))
-> GSProgram r prg -> GenState (GSProgram r prg)
forall a b. (a -> b) -> a -> b
$ Name -> Name -> [FS (r FileData)] -> GSProgram r prg
forall (r :: * -> *) vis smt md prg.
ProgramSym r vis smt md prg =>
Name -> Name -> [FS (r FileData)] -> GSProgram r prg
Proc.prog Name
n Name
p [FS (r FileData)]
ms

-- | Generates either a single module or many modules, based on the users choice
-- of modularity.
chooseModulesProc
  :: (ProcProg r vis smt md prg, NativeVector r)
  => Modularity -> GenState [FS (r File)]
chooseModulesProc :: forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
Modularity -> GenState [FS (r FileData)]
chooseModulesProc Modularity
Unmodular = State DrasilState (FS (r FileData))
-> State DrasilState [FS (r FileData)]
forall a b. State a b -> State a [b]
liftS State DrasilState (FS (r FileData))
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState (FS (r FileData))
genUnmodularProc
chooseModulesProc Modularity
Modular = State DrasilState [FS (r FileData)]
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState [FS (r FileData)]
genModulesProc

-- | Generates an entire SCS program as a single module.
genUnmodularProc
  :: (ProcProg r vis smt md prg, NativeVector r)
  => GenState (FS (r File))
genUnmodularProc :: forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState (FS (r FileData))
genUnmodularProc = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  Name
umDesc <- GenState Name
unmodularDesc
  Name
giName <- InternalConcept -> GenState Name
genICName InternalConcept
GetInput
  Name
dvName <- InternalConcept -> GenState Name
genICName InternalConcept
DerivedValuesFn
  Name
icName <- InternalConcept -> GenState Name
genICName InternalConcept
InputConstraintsFn
  let n :: Name
n = DrasilState
g DrasilState -> Getting Name DrasilState Name -> Name
forall s a. s -> Getting a s a -> a
^. Getting Name DrasilState Name
forall c. HasSmithEtAlSRS c => Lens' c Name
Lens' DrasilState Name
programName
      cls :: Bool
cls = (Name -> Bool) -> [Name] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Name -> ModExportMap -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`member` DrasilState -> ModExportMap
clsMap DrasilState
g) [Name
giName, Name
dvName, Name
icName]
  if Bool
cls then Name -> GenState (FS (r FileData))
forall a. HasCallStack => Name -> a
error Name
"genUnmodularProc: Procedural renderers do not support classes"
  else Name
-> Name
-> [Name]
-> [GenState (Maybe (MS (r md)))]
-> GenState (FS (r FileData))
forall (r :: * -> *) vis smt md prg.
ProcProg r vis smt md prg =>
Name
-> Name
-> [Name]
-> [GenState (Maybe (MS (r md)))]
-> GenState (FS (r FileData))
genModuleWithImportsProc Name
n Name
umDesc ((ExtLibState -> [Name]) -> [ExtLibState] -> [Name]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ExtLibState -> Getting [Name] ExtLibState [Name] -> [Name]
forall s a. s -> Getting a s a -> a
^. Getting [Name] ExtLibState [Name]
Lens' ExtLibState [Name]
imports) (ExtLibMap -> [ExtLibState]
forall k a. Map k a -> [a]
elems (ExtLibMap -> [ExtLibState]) -> ExtLibMap -> [ExtLibState]
forall a b. (a -> b) -> a -> b
$ DrasilState -> ExtLibMap
extLibMap DrasilState
g))
        (GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md.
(NativeVector r, SharedProg r vis smt md) =>
GenState (Maybe (MS (r md)))
genMainFuncProc
          GenState (Maybe (MS (r md)))
-> [GenState (Maybe (MS (r md)))] -> [GenState (Maybe (MS (r md)))]
forall a. a -> [a] -> [a]
: (StateT DrasilState Identity (MS (r md))
 -> GenState (Maybe (MS (r md))))
-> [StateT DrasilState Identity (MS (r md))]
-> [GenState (Maybe (MS (r md)))]
forall a b. (a -> b) -> [a] -> [b]
map ((MS (r md) -> Maybe (MS (r md)))
-> StateT DrasilState Identity (MS (r md))
-> GenState (Maybe (MS (r md)))
forall a b.
(a -> b)
-> StateT DrasilState Identity a -> StateT DrasilState Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MS (r md) -> Maybe (MS (r md))
forall a. a -> Maybe a
Just) ((CodeDefinition -> StateT DrasilState Identity (MS (r md)))
-> [CodeDefinition] -> [StateT DrasilState Identity (MS (r md))]
forall a b. (a -> b) -> [a] -> [b]
map CodeDefinition -> StateT DrasilState Identity (MS (r md))
forall (r :: * -> *) vis smt md.
(NativeVector r, SharedProg r vis smt md) =>
CodeDefinition -> GenState (MS (r md))
genCalcFuncProc (DrasilState
g DrasilState
-> Getting [CodeDefinition] DrasilState [CodeDefinition]
-> [CodeDefinition]
forall s a. s -> Getting a s a -> a
^. Getting [CodeDefinition] DrasilState [CodeDefinition]
forall c. HasCodeSpec c => Lens' c [CodeDefinition]
Lens' DrasilState [CodeDefinition]
execOrder)
            [StateT DrasilState Identity (MS (r md))]
-> [StateT DrasilState Identity (MS (r md))]
-> [StateT DrasilState Identity (MS (r md))]
forall a. [a] -> [a] -> [a]
++ (Mod -> [StateT DrasilState Identity (MS (r md))])
-> [Mod] -> [StateT DrasilState Identity (MS (r md))]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Mod -> [StateT DrasilState Identity (MS (r md))]
forall (r :: * -> *) vis smt md.
(SharedProg r vis smt md, NativeVector r) =>
Mod -> [GenState (MS (r md))]
genModFuncsProc (DrasilState -> [Mod]
modules DrasilState
g))
          [GenState (Maybe (MS (r md)))]
-> [GenState (Maybe (MS (r md)))] -> [GenState (Maybe (MS (r md)))]
forall a. [a] -> [a] -> [a]
++ ([VisibilityTag -> GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md.
(SharedProg r vis smt md, NativeVector r) =>
VisibilityTag -> GenState (Maybe (MS (r md)))
genInputFormatProc VisibilityTag
Pub, VisibilityTag -> GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md.
(SharedProg r vis smt md, NativeVector r) =>
VisibilityTag -> GenState (Maybe (MS (r md)))
genInputDerivedProc VisibilityTag
Pub,
              VisibilityTag -> GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md.
(SharedProg r vis smt md, NativeVector r) =>
VisibilityTag -> GenState (Maybe (MS (r md)))
genInputConstraintsProc VisibilityTag
Pub] [GenState (Maybe (MS (r md)))]
-> [GenState (Maybe (MS (r md)))] -> [GenState (Maybe (MS (r md)))]
forall a. [a] -> [a] -> [a]
++ [GenState (Maybe (MS (r md)))
forall (r :: * -> *) vis smt md.
(SharedProg r vis smt md, NativeVector r) =>
GenState (Maybe (MS (r md)))
genOutputFormatProc]))

-- | Generates all modules for an SCS program.
genModulesProc
  :: (ProcProg r vis smt md prg, NativeVector r)
  => GenState [FS (r File)]
genModulesProc :: forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState [FS (r FileData)]
genModulesProc = do
  DrasilState
g <- StateT DrasilState Identity DrasilState
forall s (m :: * -> *). MonadState s m => m s
get
  FS (r FileData)
mn     <- GenState (FS (r FileData))
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState (FS (r FileData))
genMainProc
  [FS (r FileData)]
inp    <- GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState [FS (r FileData)]
genInputModProc
  Bool
con    <- GenState Bool
checkConstClass
  FS (r FileData)
cal    <- GenState (FS (r FileData))
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState (FS (r FileData))
genCalcModProc
  [FS (r FileData)]
out    <- GenState [FS (r FileData)]
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
GenState [FS (r FileData)]
genOutputModProc
  [FS (r FileData)]
moddef <- (Mod -> GenState (FS (r FileData)))
-> [Mod] -> GenState [FS (r FileData)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Mod -> GenState (FS (r FileData))
forall (r :: * -> *) vis smt md prg.
(ProcProg r vis smt md prg, NativeVector r) =>
Mod -> GenState (FS (r FileData))
genModDefProc (DrasilState -> [Mod]
modules DrasilState
g) -- hack ?
  if Bool
con then Name -> GenState [FS (r FileData)]
forall a. HasCallStack => Name -> a
error Name
"genModulesProc: Procedural renderers do not support classes"
  else [FS (r FileData)] -> GenState [FS (r FileData)]
forall a. a -> StateT DrasilState Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return ([FS (r FileData)] -> GenState [FS (r FileData)])
-> [FS (r FileData)] -> GenState [FS (r FileData)]
forall a b. (a -> b) -> a -> b
$ FS (r FileData)
mn FS (r FileData) -> [FS (r FileData)] -> [FS (r FileData)]
forall a. a -> [a] -> [a]
: [FS (r FileData)]
inp [FS (r FileData)] -> [FS (r FileData)] -> [FS (r FileData)]
forall a. [a] -> [a] -> [a]
++ FS (r FileData)
cal FS (r FileData) -> [FS (r FileData)] -> [FS (r FileData)]
forall a. a -> [a] -> [a]
: [FS (r FileData)]
out [FS (r FileData)] -> [FS (r FileData)] -> [FS (r FileData)]
forall a. [a] -> [a] -> [a]
++ [FS (r FileData)]
moddef

-- | Private utilities used in 'generateCode'.
getDir :: Lang -> String
getDir :: Lang -> Name
getDir Lang
Cpp = Name
"cpp"
getDir Lang
CSharp = Name
"csharp"
getDir Lang
Java = Name
"java"
getDir Lang
Python = Name
"python"
getDir Lang
Swift = Name
"swift"
getDir Lang
Julia = Name
"julia"
getDir Lang
Matlab = Name
"matlab"