-- | Defines generation functions for SCS code packages.
module Language.Drasil.Code.Imperative.Generator (
  generator, generateCode
) where

import Language.Drasil
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)
import Language.Drasil.Code.Imperative.GenODE (chooseODELib)
import Language.Drasil.Code.Imperative.Helpers (liftS)
import Language.Drasil.Code.Imperative.Import (genModDef, genModFuncs,
  genModClasses)
import Language.Drasil.Code.Imperative.Modules (chooseInModule, genConstClass,
  genConstMod, genInputClass, genInputConstraints, genInputDerived,
  genInputFormat, genMain, genMainFunc, genCalcMod, genCalcFunc,
  genOutputFormat, genOutputMod, genSampleInput)
import Language.Drasil.Code.Imperative.DrasilState (GenState, DrasilState(..),
  designLog, inMod, modExportMap, clsDefMap)
import Language.Drasil.Code.Imperative.GOOL.ClassInterface (ReadMeInfo(..),
  PackageSym(..), AuxiliarySym(..))
import Language.Drasil.Code.Imperative.GOOL.Data (PackData(..), ad)
import Language.Drasil.Code.Imperative.GOOL.LanguageRenderer(sampleInputName)
import Language.Drasil.Code.CodeGeneration (createCodeFiles, makeCode)
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(..))
import Language.Drasil.CodeSpec (CodeSpec(..), getODE)
import Language.Drasil.Printers (SingleLine(OneLine), sentenceDoc)

import GOOL.Drasil (GSProgram, SFile, OOProg, ProgramSym(..), ScopeTag(..),
  ProgData(..), initialState, unCI)

import System.Directory (setCurrentDirectory, createDirectoryIfMissing,
  getCurrentDirectory)
import Control.Lens ((^.))
import Control.Monad.State (get, evalState, runState)
import Data.List (nub)
import Data.Map (fromList, member, keys, elems)
import Data.Maybe (maybeToList, catMaybes)
import Text.PrettyPrint.HughesPJ (isEmpty, vcat)

-- | 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 -> String -> [Expr] -> Choices -> CodeSpec -> DrasilState
generator Lang
l String
dt [Expr]
sd Choices
chs CodeSpec
spec = DrasilState {
  -- constants
  codeSpec :: CodeSpec
codeSpec = CodeSpec
spec,
  modular :: Modularity
modular = Architecture -> Modularity
modularity forall a b. (a -> b) -> a -> b
$ Choices -> Architecture
architecture Choices
chs,
  inStruct :: Structure
inStruct = DataInfo -> Structure
inputStructure forall a b. (a -> b) -> a -> b
$ Choices -> DataInfo
dataInfo Choices
chs,
  conStruct :: ConstantStructure
conStruct = DataInfo -> ConstantStructure
constStructure forall a b. (a -> b) -> a -> b
$ Choices -> DataInfo
dataInfo Choices
chs,
  conRepr :: ConstantRepr
conRepr = DataInfo -> ConstantRepr
constRepr forall a b. (a -> b) -> a -> b
$ Choices -> DataInfo
dataInfo Choices
chs,
  concMatches :: MatchedConceptMap
concMatches = MatchedConceptMap
mcm,
  spaceMatches :: MatchedSpaces
spaceMatches = Lang -> Choices -> MatchedSpaces
chooseSpace Lang
l Choices
chs,
  implType :: ImplementationType
implType = Architecture -> ImplementationType
impType forall a b. (a -> b) -> a -> b
$ Choices -> Architecture
architecture Choices
chs,
  onSfwrC :: ConstraintBehaviour
onSfwrC = Constraints -> ConstraintBehaviour
onSfwrConstraint forall a b. (a -> b) -> a -> b
$ Choices -> Constraints
srsConstraints Choices
chs,
  onPhysC :: ConstraintBehaviour
onPhysC = Constraints -> ConstraintBehaviour
onPhysConstraint forall a b. (a -> b) -> a -> b
$ Choices -> Constraints
srsConstraints Choices
chs,
  commented :: [Comments]
commented = DocConfig -> [Comments]
comments forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> DocConfig
docConfig forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs,
  doxOutput :: Verbosity
doxOutput = DocConfig -> Verbosity
doxVerbosity forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> DocConfig
docConfig forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs,
  date :: String
date = Visibility -> String
showDate forall a b. (a -> b) -> a -> b
$ DocConfig -> Visibility
dates forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> DocConfig
docConfig forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs,
  logKind :: [Logging]
logKind  = LogConfig -> [Logging]
logging forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> LogConfig
logConfig forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs,
  logName :: String
logName = LogConfig -> String
logFile forall a b. (a -> b) -> a -> b
$ OptionalFeatures -> LogConfig
logConfig forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs,
  auxiliaries :: [AuxFile]
auxiliaries = OptionalFeatures -> [AuxFile]
auxFiles forall a b. (a -> b) -> a -> b
$ Choices -> OptionalFeatures
optFeats Choices
chs,
  sampleData :: [Expr]
sampleData = [Expr]
sd,
  modules :: [Mod]
modules = [Mod]
modules',
  extLibNames :: [(String, String)]
extLibNames = [(String, String)]
nms,
  extLibMap :: ExtLibMap
extLibMap = forall k a. Ord k => [(k, a)] -> Map k a
fromList [(String, ExtLibState)]
elmap,
  libPaths :: [String]
libPaths = forall a. Maybe a -> [a]
maybeToList Maybe String
pth,
  eMap :: ModExportMap
eMap = ModExportMap
mem,
  libEMap :: ModExportMap
libEMap = ModExportMap
lem,
  clsMap :: ModExportMap
clsMap = ModExportMap
cdm,
  defList :: [String]
defList = forall a. Eq a => [a] -> [a]
nub forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [k]
keys ModExportMap
mem forall a. [a] -> [a] -> [a]
++ forall k a. Map k a -> [k]
keys ModExportMap
cdm,
  getVal :: Int
getVal = Choices -> Int
folderVal Choices
chs,
  -- stateful
  currentModule :: String
currentModule = String
"",
  currentClass :: String
currentClass = String
"",
  _designLog :: Doc
_designLog = Doc
des,
  _loggedSpaces :: [(Space, CodeType)]
_loggedSpaces = [] -- Used to prevent duplicate logs added to design log
}
  where (MatchedConceptMap
mcm, [Sentence]
concLog) = forall s a. State s a -> s -> (a, s)
runState (Choices -> State [Sentence] MatchedConceptMap
chooseConcept Choices
chs) []
        showDate :: Visibility -> String
showDate Visibility
Show = String
dt
        showDate Visibility
Hide = String
""
        ((Maybe String
pth, [(String, ExtLibState)]
elmap, (String, String)
lname), [Sentence]
libLog) = forall s a. State s a -> s -> (a, s)
runState (Lang -> Maybe ODE -> State [Sentence] ODEGenInfo
chooseODELib Lang
l forall a b. (a -> b) -> a -> b
$ [ExtLib] -> Maybe ODE
getODE forall a b. (a -> b) -> a -> b
$ Choices -> [ExtLib]
extLibs Choices
chs) []
        els :: [ExtLibState]
els = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(String, ExtLibState)]
elmap
        nms :: [(String, String)]
nms = [(String, String)
lname]
        mem :: ModExportMap
mem = CodeSpec -> Choices -> [Mod] -> ModExportMap
modExportMap CodeSpec
spec Choices
chs [Mod]
modules'
        lem :: ModExportMap
lem = forall k a. Ord k => [(k, a)] -> Map k a
fromList (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall s a. s -> Getting a s a -> a
^. Lens' ExtLibState [(String, String)]
modExports) [ExtLibState]
els)
        cdm :: ModExportMap
cdm = CodeSpec -> Choices -> [Mod] -> ModExportMap
clsDefMap CodeSpec
spec Choices
chs [Mod]
modules'
        modules' :: [Mod]
modules' = CodeSpec -> [Mod]
mods CodeSpec
spec forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall s a. s -> Getting a s a -> a
^. Lens' ExtLibState [Mod]
auxMods) [ExtLibState]
els
        nonPrefChs :: [Sentence]
nonPrefChs = Choices -> [Sentence]
choicesSent Choices
chs
        des :: Doc
des = [Doc] -> Doc
vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (ChunkDB -> Stage -> SingleLine -> Sentence -> Doc
sentenceDoc (CodeSpec -> ChunkDB
sysinfodb CodeSpec
spec) Stage
Implementation SingleLine
OneLine) forall a b. (a -> b) -> a -> b
$
          ([Sentence]
nonPrefChs forall a. [a] -> [a] -> [a]
++ [Sentence]
concLog forall a. [a] -> [a] -> [a]
++ [Sentence]
libLog)

-- | Generates a package with the given 'DrasilState'. The passed
-- un-representation functions determine which target language the package will
-- be generated in.
generateCode :: (OOProg progRepr, PackageSym packRepr) => Lang ->
  (progRepr (Program progRepr) -> ProgData) -> (packRepr (Package packRepr) ->
  PackData) -> DrasilState -> IO ()
generateCode :: forall (progRepr :: * -> *) (packRepr :: * -> *).
(OOProg progRepr, PackageSym packRepr) =>
Lang
-> (progRepr (Program progRepr) -> ProgData)
-> (packRepr (Package packRepr) -> PackData)
-> DrasilState
-> IO ()
generateCode Lang
l progRepr (Program progRepr) -> ProgData
unReprProg packRepr (Package packRepr) -> PackData
unReprPack DrasilState
g = do
  String
workingDir <- IO String
getCurrentDirectory
  Bool -> String -> IO ()
createDirectoryIfMissing Bool
False (Lang -> String
getDir Lang
l)
  String -> IO ()
setCurrentDirectory (Lang -> String
getDir Lang
l)
  let (packRepr (Package packRepr)
pckg, DrasilState
ds) = forall s a. State s a -> s -> (a, s)
runState (forall (progRepr :: * -> *) (packRepr :: * -> *).
(OOProg progRepr, PackageSym packRepr) =>
(progRepr (Program progRepr) -> ProgData)
-> GenState (packRepr (Package packRepr))
genPackage progRepr (Program progRepr) -> ProgData
unReprProg) DrasilState
g
      baseAux :: [AuxData]
baseAux = [String -> Doc -> AuxData
ad String
"designLog.txt" (DrasilState
ds forall s a. s -> Getting a s a -> a
^. Lens' DrasilState Doc
designLog) | Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Doc -> Bool
isEmpty forall a b. (a -> b) -> a -> b
$
          DrasilState
ds forall s a. s -> Getting a s a -> a
^. Lens' DrasilState Doc
designLog] forall a. [a] -> [a] -> [a]
++ PackData -> [AuxData]
packAux (packRepr (Package packRepr) -> PackData
unReprPack packRepr (Package packRepr)
pckg)
      aux :: [AuxData]
aux
        | Lang
l forall a. Eq a => a -> a -> Bool
== Lang
Python = String -> Doc -> AuxData
ad String
"__init__.py" forall a. Monoid a => a
mempty forall a. a -> [a] -> [a]
: [AuxData]
baseAux
        | Bool
otherwise   = [AuxData]
baseAux
      code :: Code
code = [FileData] -> [AuxData] -> Code
makeCode (ProgData -> [FileData]
progMods forall a b. (a -> b) -> a -> b
$ PackData -> ProgData
packProg forall a b. (a -> b) -> a -> b
$ packRepr (Package packRepr) -> PackData
unReprPack packRepr (Package packRepr)
pckg) [AuxData]
aux
  Code -> IO ()
createCodeFiles Code
code
  String -> IO ()
setCurrentDirectory String
workingDir

-- | 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, PackageSym packRepr) =>
  (progRepr (Program progRepr) -> ProgData) ->
  GenState (packRepr (Package packRepr))
genPackage :: forall (progRepr :: * -> *) (packRepr :: * -> *).
(OOProg progRepr, PackageSym packRepr) =>
(progRepr (Program progRepr) -> ProgData)
-> GenState (packRepr (Package packRepr))
genPackage progRepr (Program progRepr) -> ProgData
unRepr = do
  DrasilState
g <- forall s (m :: * -> *). MonadState s m => m s
get
  State GOOLState (CodeInfo GOOLState)
ci <- forall (r :: * -> *). OOProg r => GenState (GSProgram r)
genProgram
  State GOOLState (progRepr (Program progRepr))
p <- forall (r :: * -> *). OOProg r => GenState (GSProgram r)
genProgram
  let info :: GOOLState
info = forall a. CodeInfo a -> a
unCI forall a b. (a -> b) -> a -> b
$ forall s a. State s a -> s -> a
evalState State GOOLState (CodeInfo GOOLState)
ci GOOLState
initialState
      (progRepr (Program progRepr)
reprPD, GOOLState
s) = forall s a. State s a -> s -> (a, s)
runState State GOOLState (progRepr (Program progRepr))
p GOOLState
info
      pd :: ProgData
pd = progRepr (Program progRepr) -> ProgData
unRepr progRepr (Program progRepr)
reprPD
      m :: packRepr (Auxiliary packRepr)
m = forall (r :: * -> *).
AuxiliarySym r =>
[String]
-> ImplementationType
-> [Comments]
-> GOOLState
-> ProgData
-> r (Auxiliary r)
makefile (DrasilState -> [String]
libPaths DrasilState
g) (DrasilState -> ImplementationType
implType DrasilState
g) (DrasilState -> [Comments]
commented DrasilState
g) GOOLState
s ProgData
pd
      as :: [String]
as = case DrasilState -> CodeSpec
codeSpec DrasilState
g of CodeSpec {authors :: ()
authors = [a]
a} -> forall a b. (a -> b) -> [a] -> [b]
map forall n. HasName n => n -> String
name [a]
a
      cfp :: [String]
cfp = CodeSpec -> [String]
configFiles forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g
      db :: ChunkDB
db = CodeSpec -> ChunkDB
sysinfodb forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g
      prps :: String
prps = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ChunkDB -> Stage -> SingleLine -> Sentence -> Doc
sentenceDoc ChunkDB
db Stage
Implementation SingleLine
OneLine
        ([Sentence] -> Sentence
foldlSent forall a b. (a -> b) -> a -> b
$ CodeSpec -> [Sentence]
purpose forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g)
      bckgrnd :: String
bckgrnd = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ChunkDB -> Stage -> SingleLine -> Sentence -> Doc
sentenceDoc ChunkDB
db Stage
Implementation SingleLine
OneLine
        ([Sentence] -> Sentence
foldlSent forall a b. (a -> b) -> a -> b
$ CodeSpec -> [Sentence]
background forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g)
  Maybe (packRepr (Auxiliary packRepr))
i <- forall (r :: * -> *).
AuxiliarySym r =>
GenState (Maybe (r (Auxiliary r)))
genSampleInput
  Maybe (packRepr (Auxiliary packRepr))
d <- forall (r :: * -> *).
AuxiliarySym r =>
GOOLState -> GenState (Maybe (r (Auxiliary r)))
genDoxConfig GOOLState
s
  Maybe (packRepr (Auxiliary packRepr))
rm <- forall (r :: * -> *).
AuxiliarySym r =>
ReadMeInfo -> GenState (Maybe (r (Auxiliary r)))
genReadMe ReadMeInfo {
        langName :: String
langName = String
"",
        langVersion :: String
langVersion = String
"",
        invalidOS :: Maybe String
invalidOS = forall a. Maybe a
Nothing,
        implementType :: ImplementationType
implementType = DrasilState -> ImplementationType
implType DrasilState
g,
        extLibNV :: [(String, String)]
extLibNV = DrasilState -> [(String, String)]
extLibNames DrasilState
g,
        extLibFP :: [String]
extLibFP = DrasilState -> [String]
libPaths DrasilState
g,
        contributors :: [String]
contributors = [String]
as,
        configFP :: [String]
configFP = [String]
cfp,
        caseName :: String
caseName = String
"",
        examplePurpose :: String
examplePurpose = String
prps,
        exampleDescr :: String
exampleDescr = String
bckgrnd,
        folderNum :: Int
folderNum = DrasilState -> Int
getVal DrasilState
g,
        inputOutput :: (String, String)
inputOutput = (String
sampleInputName, String
"output.txt")} -- This needs a more permanent solution
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (r :: * -> *).
PackageSym r =>
ProgData -> [r (Auxiliary r)] -> r (Package r)
package ProgData
pd (packRepr (Auxiliary packRepr)
mforall a. a -> [a] -> [a]
:forall a. [Maybe a] -> [a]
catMaybes [Maybe (packRepr (Auxiliary packRepr))
i,Maybe (packRepr (Auxiliary packRepr))
rm,Maybe (packRepr (Auxiliary packRepr))
d])

-- | Generates an SCS program based on the problem and the user's design choices.
genProgram :: (OOProg r) => GenState (GSProgram r)
genProgram :: forall (r :: * -> *). OOProg r => GenState (GSProgram r)
genProgram = do
  DrasilState
g <- forall s (m :: * -> *). MonadState s m => m s
get
  [FS (r (File r))]
ms <- forall (r :: * -> *). OOProg r => Modularity -> GenState [SFile r]
chooseModules forall a b. (a -> b) -> a -> b
$ DrasilState -> Modularity
modular DrasilState
g
  let n :: String
n = CodeSpec -> String
pName forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g
  let p :: String
p = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ ChunkDB -> Stage -> SingleLine -> Sentence -> Doc
sentenceDoc (CodeSpec -> ChunkDB
sysinfodb forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g) Stage
Implementation SingleLine
OneLine forall a b. (a -> b) -> a -> b
$ [Sentence] -> Sentence
foldlSent forall a b. (a -> b) -> a -> b
$ CodeSpec -> [Sentence]
purpose forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (r :: * -> *).
ProgramSym r =>
String -> String -> [SFile r] -> GSProgram r
prog String
n String
p [FS (r (File r))]
ms

-- | Generates either a single module or many modules, based on the users choice
-- of modularity.
chooseModules :: (OOProg r) => Modularity -> GenState [SFile r]
chooseModules :: forall (r :: * -> *). OOProg r => Modularity -> GenState [SFile r]
chooseModules Modularity
Unmodular = forall a b. State a b -> State a [b]
liftS forall (r :: * -> *). OOProg r => GenState (SFile r)
genUnmodular
chooseModules (Modular InputModule
_) = forall (r :: * -> *). OOProg r => GenState [SFile r]
genModules

-- | Generates an entire SCS program as a single module.
genUnmodular :: (OOProg r) => GenState (SFile r)
genUnmodular :: forall (r :: * -> *). OOProg r => GenState (SFile r)
genUnmodular = do
  DrasilState
g <- forall s (m :: * -> *). MonadState s m => m s
get
  String
umDesc <- GenState String
unmodularDesc
  let n :: String
n = CodeSpec -> String
pName forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g
      cls :: Bool
cls = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall k a. Ord k => k -> Map k a -> Bool
`member` DrasilState -> ModExportMap
clsMap DrasilState
g)
        [String
"get_input", String
"derived_values", String
"input_constraints"]
  forall (r :: * -> *).
OOProg r =>
String
-> String
-> [String]
-> [GenState (Maybe (SMethod r))]
-> [GenState (Maybe (SClass r))]
-> GenState (SFile r)
genModuleWithImports String
n String
umDesc (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall s a. s -> Getting a s a -> a
^. Lens' ExtLibState [String]
imports) (forall k a. Map k a -> [a]
elems forall a b. (a -> b) -> a -> b
$ DrasilState -> ExtLibMap
extLibMap DrasilState
g))
    (forall (r :: * -> *). OOProg r => GenState (Maybe (SMethod r))
genMainFunc
      forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just) (forall a b. (a -> b) -> [a] -> [b]
map forall (r :: * -> *).
OOProg r =>
CodeDefinition -> GenState (SMethod r)
genCalcFunc (CodeSpec -> [CodeDefinition]
execOrder forall a b. (a -> b) -> a -> b
$ DrasilState -> CodeSpec
codeSpec DrasilState
g)
        forall a. [a] -> [a] -> [a]
++ forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall (r :: * -> *). OOProg r => Mod -> [GenState (SMethod r)]
genModFuncs (DrasilState -> [Mod]
modules DrasilState
g))
      forall a. [a] -> [a] -> [a]
++ ((if Bool
cls then [] else [forall (r :: * -> *).
OOProg r =>
ScopeTag -> GenState (Maybe (SMethod r))
genInputFormat ScopeTag
Pub, forall (r :: * -> *).
OOProg r =>
ScopeTag -> GenState (Maybe (SMethod r))
genInputDerived ScopeTag
Pub,
        forall (r :: * -> *).
OOProg r =>
ScopeTag -> GenState (Maybe (SMethod r))
genInputConstraints ScopeTag
Pub]) forall a. [a] -> [a] -> [a]
++ [forall (r :: * -> *). OOProg r => GenState (Maybe (SMethod r))
genOutputFormat]))
    ([forall (r :: * -> *).
OOProg r =>
ClassType -> GenState (Maybe (SClass r))
genInputClass ClassType
Auxiliary, forall (r :: * -> *).
OOProg r =>
ClassType -> GenState (Maybe (SClass r))
genConstClass ClassType
Auxiliary]
      forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Maybe a
Just) (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall (r :: * -> *). OOProg r => Mod -> [GenState (SClass r)]
genModClasses forall a b. (a -> b) -> a -> b
$ DrasilState -> [Mod]
modules DrasilState
g))

-- | Generates all modules for an SCS program.
genModules :: (OOProg r) => GenState [SFile r]
genModules :: forall (r :: * -> *). OOProg r => GenState [SFile r]
genModules = do
  DrasilState
g <- forall s (m :: * -> *). MonadState s m => m s
get
  SFile r
mn     <- forall (r :: * -> *). OOProg r => GenState (SFile r)
genMain
  [SFile r]
inp    <- forall (r :: * -> *). OOProg r => InputModule -> GenState [SFile r]
chooseInModule forall a b. (a -> b) -> a -> b
$ DrasilState -> InputModule
inMod DrasilState
g
  [SFile r]
con    <- forall (r :: * -> *). OOProg r => GenState [SFile r]
genConstMod
  SFile r
cal    <- forall (r :: * -> *). OOProg r => GenState (SFile r)
genCalcMod
  [SFile r]
out    <- forall (r :: * -> *). OOProg r => GenState [SFile r]
genOutputMod
  [SFile r]
moddef <- forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall (r :: * -> *). OOProg r => Mod -> GenState (SFile r)
genModDef (DrasilState -> [Mod]
modules DrasilState
g) -- hack ?
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ SFile r
mn forall a. a -> [a] -> [a]
: [SFile r]
inp forall a. [a] -> [a] -> [a]
++ [SFile r]
con forall a. [a] -> [a] -> [a]
++ SFile r
cal forall a. a -> [a] -> [a]
: [SFile r]
out forall a. [a] -> [a] -> [a]
++ [SFile r]
moddef

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