Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unmodular choice for code generation #2005

Merged
merged 20 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8947dd5
Add infrastructure for modularity choice
bmaclach Feb 3, 2020
70a44ea
Make InputModule combined/separated choice a sub-choice of modularity…
bmaclach Feb 3, 2020
a97ae1b
Change types of arguments to genModule to be closer to reduce amount …
bmaclach Feb 4, 2020
9fec950
Implement unmodular choice
bmaclach Feb 4, 2020
5e652d0
Fixed state problems in C++ - wrong file name in doxygen comments in …
bmaclach Feb 4, 2020
698186a
Store program name in CodeSpec instead of entire program CommonIdea -…
bmaclach Feb 4, 2020
0fc9a52
Update module definition and export maps based on modularity
bmaclach Feb 4, 2020
872e2a5
Fix condition for generating input class -- only care about constants…
bmaclach Feb 5, 2020
6b1979c
Improve condition for adding header import to work for when main func…
bmaclach Feb 5, 2020
fdb90b2
Fix conditions for generating declarations of inputs/constants to und…
bmaclach Feb 5, 2020
00abc28
Replace defMap with clsMap and defList -- clsMap provides the actual …
bmaclach Feb 5, 2020
56c7f72
Update logic for how to access a variable that is an input when Bundl…
bmaclach Feb 5, 2020
3f0f0a5
Consider case where constructors are not external. Unmodular projectile
bmaclach Feb 5, 2020
404a768
Use state in Python to print main function last
bmaclach Feb 5, 2020
6748d73
Fixed mistakes with prior work from this PR - had assumed input would…
bmaclach Feb 5, 2020
24e0e9c
Only one public class per module (Java requires this)
bmaclach Feb 5, 2020
ec17829
Fix bug where exceptions from transitive calls were not being declare…
bmaclach Feb 6, 2020
926b00e
Linted
bmaclach Feb 6, 2020
1310a08
Fix incorrect condition for initializing constants
bmaclach Feb 6, 2020
9814206
Update stable
bmaclach Feb 6, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions code/drasil-code/Language/Drasil/Code.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ module Language.Drasil.Code (
($:=), Choices(..), CodeSpec(..), CodeSystInfo(..), Comments(..),
Verbosity(..), ConstraintBehaviour(..), Func, FuncStmt(..),
ImplementationType(..), Lang(..), Logging(LogNone, LogAll), Mod(Mod),
Structure(..), ConstantStructure(..), ConstantRepr(..), InputModule(..),
CodeConcept(..), matchConcepts, AuxFile(..), Visibility(..),
Modularity(..), Structure(..), ConstantStructure(..), ConstantRepr(..),
InputModule(..), CodeConcept(..), matchConcepts, AuxFile(..), Visibility(..),
asExpr, asExpr', asVC, asVC', codeSpec, fdec, ffor, funcData, funcDef,
packmod, relToQD,
junkLine, multiLine, repeated, singleLine, singleton,
Expand All @@ -31,9 +31,10 @@ import Language.Drasil.Code.DataDesc (junkLine, multiLine, repeated, singleLine,
import Language.Drasil.CodeSpec (($:=), Choices(..), CodeSpec(..),
CodeSystInfo(..), Comments(..), Verbosity(..), ConstraintBehaviour(..), Func,
FuncStmt(..), ImplementationType(..), Lang(..), Logging(..), Mod(Mod),
Structure(..), ConstantStructure(..), ConstantRepr(..), InputModule(..),
CodeConcept(..), matchConcepts, AuxFile(..), Visibility(..), asExpr, asExpr',
asVC, asVC', codeSpec, fdec, ffor, funcData, funcDef, packmod, relToQD)
Modularity(..), Structure(..), ConstantStructure(..), ConstantRepr(..),
InputModule(..), CodeConcept(..), matchConcepts, AuxFile(..), Visibility(..),
asExpr, asExpr', asVC, asVC', codeSpec, fdec, ffor, funcData, funcDef,
packmod, relToQD)

import Language.Drasil.Code.Imperative.GOOL.Symantics (PackageSym(..))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Language.Drasil.Code.Imperative.Comments (

import Language.Drasil
import Database.Drasil (defTable)
import Language.Drasil.Code.Imperative.State (DrasilState(..))
import Language.Drasil.Code.Imperative.DrasilState (DrasilState(..))
import Language.Drasil.CodeSpec (CodeSpec(..), CodeSystInfo(..))
import Language.Drasil.Printers (Linearity(Linear), sentenceDoc, unitDoc)

Expand Down
30 changes: 15 additions & 15 deletions code/drasil-code/Language/Drasil/Code/Imperative/Descriptions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Language.Drasil.Code.Imperative.Descriptions (
import Utils.Drasil (stringList)

import Language.Drasil
import Language.Drasil.Code.Imperative.State (DrasilState(..))
import Language.Drasil.Code.Imperative.DrasilState (DrasilState(..), inMod)
import Language.Drasil.Chunk.Code (CodeIdea(codeName))
import Language.Drasil.CodeSpec (CodeSpec(..), CodeSystInfo(..),
InputModule(..), Structure(..))
Expand Down Expand Up @@ -44,11 +44,11 @@ inputConstructorDesc = do
idDesc True = "calculating derived values"
icDesc False = ""
icDesc True = "checking " ++ pAndS ++ " on the input"
dm = defMap $ codeSpec g
dl = defList $ codeSpec g
return $ "Initializes input object by " ++ stringList [
ifDesc (member "get_input" dm),
idDesc (member "derived_values" dm),
icDesc (member "input_constraints" dm)]
ifDesc ("get_input" `elem` dl),
idDesc ("derived_values" `elem` dl),
icDesc ("input_constraints" `elem` dl)]

inputFormatDesc :: Reader DrasilState String
inputFormatDesc = do
Expand Down Expand Up @@ -95,12 +95,12 @@ inputClassDesc = do
inClassD [] = ""
inClassD _ = "Structure for holding the " ++ stringList [
inPs $ extInputs $ csi $ codeSpec g,
dVs $ Map.lookup "derived_values" (defMap $ codeSpec g),
dVs $ "derived_values" `elem` defList (codeSpec g),
cVs $ filter (flip member (Map.filter (cname ==)
(eMap $ codeSpec g)) . codeName) (constants $ csi $ codeSpec g)]
inPs [] = ""
inPs _ = "input values"
dVs Nothing = ""
dVs False = ""
dVs _ = "derived values"
cVs [] = ""
cVs _ = "constant values"
Expand All @@ -117,32 +117,32 @@ constClassDesc = do
inFmtFuncDesc :: Reader DrasilState String
inFmtFuncDesc = do
g <- ask
let ifDesc Nothing = ""
let ifDesc False = ""
ifDesc _ = "Reads input from a file with the given file name"
return $ ifDesc $ Map.lookup "get_input" (defMap $ codeSpec g)
return $ ifDesc $ "get_input" `elem` defList (codeSpec g)

inConsFuncDesc :: Reader DrasilState String
inConsFuncDesc = do
g <- ask
pAndS <- physAndSfwrCons
let icDesc Nothing = ""
let icDesc False = ""
icDesc _ = "Verifies that input values satisfy the " ++ pAndS
return $ icDesc $ Map.lookup "input_constraints" (defMap $ codeSpec g)
return $ icDesc $ "input_constraints" `elem` defList (codeSpec g)

dvFuncDesc :: Reader DrasilState String
dvFuncDesc = do
g <- ask
let dvDesc Nothing = ""
let dvDesc False = ""
dvDesc _ = "Calculates values that can be immediately derived from the" ++
" inputs"
return $ dvDesc $ Map.lookup "derived_values" (defMap $ codeSpec g)
return $ dvDesc $ "derived_values" `elem` defList (codeSpec g)

woFuncDesc :: Reader DrasilState String
woFuncDesc = do
g <- ask
let woDesc Nothing = ""
let woDesc False = ""
woDesc _ = "Writes the output values to output.txt"
return $ woDesc $ Map.lookup "write_output" (defMap $ codeSpec g)
return $ woDesc $ "write_output" `elem` defList (codeSpec g)

physAndSfwrCons :: Reader DrasilState String
physAndSfwrCons = do
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
module Language.Drasil.Code.Imperative.State (
DrasilState(..)
module Language.Drasil.Code.Imperative.DrasilState (
DrasilState(..), inMod
) where

import Language.Drasil
import Language.Drasil.CodeSpec (AuxFile, CodeSpec, Comments, Verbosity,
MatchedConceptMap, ConstantRepr, ConstantStructure, ConstraintBehaviour,
InputModule, Logging, Structure)
import Language.Drasil.CodeSpec (AuxFile, CodeSpec, Modularity(..), Comments,
Verbosity, MatchedConceptMap, ConstantRepr, ConstantStructure,
ConstraintBehaviour, InputModule(..), Logging, Structure)

-- Private State, used to push these options around the generator
data DrasilState = DrasilState {
codeSpec :: CodeSpec,
date :: String,
modular :: Modularity,
inStruct :: Structure,
conStruct :: ConstantStructure,
conRepr :: ConstantRepr,
inMod :: InputModule,
logName :: String,
logKind :: Logging,
commented :: [Comments],
Expand All @@ -23,7 +23,13 @@ data DrasilState = DrasilState {
auxiliaries :: [AuxFile],
sampleData :: [Expr],
currentModule :: String,
currentClass :: String,

onSfwrC :: ConstraintBehaviour,
onPhysC :: ConstraintBehaviour
}
}

inMod :: DrasilState -> InputModule
inMod ds = inMod' $ modular ds
where inMod' Unmodular = Combined
inMod' (Modular im) = im
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Language.Drasil.Code.Imperative.Logging (maybeLog)
import Language.Drasil.Code.Imperative.Parameters (getCalcParams,
getConstraintParams, getDerivedIns, getDerivedOuts, getInputFormatIns,
getInputFormatOuts, getOutputParams)
import Language.Drasil.Code.Imperative.State (DrasilState(..))
import Language.Drasil.Code.Imperative.DrasilState (DrasilState(..))
import Language.Drasil.Chunk.Code (CodeIdea(codeName), codeType)
import Language.Drasil.Chunk.CodeDefinition (CodeDefinition)
import Language.Drasil.Chunk.CodeQuantity (HasCodeType)
Expand All @@ -22,6 +22,7 @@ import GOOL.Drasil (ProgramSym, TypeSym(..), ValueSym(..), StatementSym(..),
import Data.List ((\\), intersect)
import qualified Data.Map as Map (lookup)
import Data.Maybe (maybe, catMaybes)
import Control.Applicative ((<|>))
import Control.Monad.Reader (Reader, ask)
import Control.Lens ((^.))

Expand Down Expand Up @@ -95,10 +96,12 @@ getInOutCall n inFunc outFunc = do
getCall :: String -> Reader DrasilState (Maybe String)
getCall n = do
g <- ask
let getCallExported Nothing = getCallDefined (Map.lookup n $ defMap $
let currc = currentClass g
getCallExported Nothing = getCallInClass (Map.lookup n $ clsMap $
codeSpec g)
getCallExported m = return m
getCallDefined Nothing = return Nothing
getCallDefined (Just m) = if m == currentModule g then return (Just m)
getCallInClass Nothing = return Nothing
getCallInClass (Just c) = if c == currc then return $ Map.lookup c (eMap
$ codeSpec g) <|> error (c ++ " class missing from export map")
else return Nothing
getCallExported $ Map.lookup n (eMap $ codeSpec g)
39 changes: 26 additions & 13 deletions code/drasil-code/Language/Drasil/Code/Imperative/GenerateGOOL.hs
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
module Language.Drasil.Code.Imperative.GenerateGOOL (
genModule, genDoxConfig, publicClass, fApp, fAppInOut, mkParam
genModule, genDoxConfig, publicClass, privateClass, fApp, fAppInOut, mkParam
) where

import Language.Drasil
import Language.Drasil.Code.Imperative.State (DrasilState(..))
import Language.Drasil.Code.Imperative.DrasilState (DrasilState(..))
import Language.Drasil.Code.Imperative.GOOL.Symantics (AuxiliarySym(..))
import Language.Drasil.CodeSpec (CodeSpec(..), CodeSystInfo(..), Comments(..),
Name)

import GOOL.Drasil (Label, ProgramSym, FileSym(..), TypeSym(..),
VariableSym(..), ValueSym(..), ValueExpression(..), StatementSym(..),
ParameterSym(..), MethodSym(..), StateVarSym(..), ClassSym(..), ModuleSym(..),
CodeType(..), GOOLState, FS, CS, MS, VS, lensMStoVS)
CodeType(..), ScopeTag(..), GOOLState, FS, CS, MS, VS, lensMStoVS)

import Control.Lens.Zoom (zoom)
import qualified Data.Map as Map (lookup)
import Data.Maybe (maybe)
import Data.Maybe (catMaybes)
import Control.Monad.Reader (Reader, ask, withReader)

genModule :: (ProgramSym repr) => Name -> String
-> Maybe (Reader DrasilState [MS (repr (Method repr))])
-> Maybe (Reader DrasilState [CS (repr (Class repr))])
-> [Reader DrasilState (Maybe (MS (repr (Method repr))))]
-> [Reader DrasilState (Maybe (CS (repr (Class repr))))]
-> Reader DrasilState (FS (repr (RenderFile repr)))
genModule n desc maybeMs maybeCs = do
g <- ask
let updateState = withReader (\s -> s { currentModule = n })
-- Below line of code cannot be simplified because authors has a generic type
as = case csi (codeSpec g) of CSI {authors = a} -> map name a
cs <- maybe (return []) updateState maybeCs
ms <- maybe (return []) updateState maybeMs
cs <- mapM updateState maybeCs
ms <- mapM updateState maybeMs
let commMod | CommentMod `elem` commented g = docMod desc
as (date g)
| CommentFunc `elem` commented g && not (null ms) = docMod "" []
(date g)
| otherwise = id
return $ commMod $ fileDoc $ buildModule n ms cs
return $ commMod $ fileDoc $ buildModule n (catMaybes ms) (catMaybes cs)

genDoxConfig :: (AuxiliarySym repr) => String -> GOOLState ->
Reader DrasilState [repr (Auxiliary repr)]
Expand All @@ -44,15 +44,28 @@ genDoxConfig n s = do
v = doxOutput g
return [doxConfig n s v | not (null cms)]

publicClass :: (ProgramSym repr) => String -> Label -> Maybe Label ->
mkClass :: (ProgramSym repr) => ScopeTag -> String -> Label -> Maybe Label ->
[CS (repr (StateVar repr))] -> Reader DrasilState [MS (repr (Method repr))]
-> Reader DrasilState (CS (repr (Class repr)))
publicClass desc n l vs mths = do
mkClass s desc n l vs mths = do
g <- ask
ms <- mths
let getFunc Pub = pubClass
getFunc Priv = privClass
f = getFunc s
return $ if CommentClass `elem` commented g
then docClass desc (pubClass n l vs ms)
else pubClass n l vs ms
then docClass desc (f n l vs ms)
else f n l vs ms

publicClass :: (ProgramSym repr) => String -> Label -> Maybe Label ->
[CS (repr (StateVar repr))] -> Reader DrasilState [MS (repr (Method repr))]
-> Reader DrasilState (CS (repr (Class repr)))
publicClass = mkClass Pub

privateClass :: (ProgramSym repr) => String -> Label -> Maybe Label ->
[CS (repr (StateVar repr))] -> Reader DrasilState [MS (repr (Method repr))]
-> Reader DrasilState (CS (repr (Class repr)))
privateClass = mkClass Priv

fApp :: (ProgramSym repr) => String -> String -> VS (repr (Type repr)) ->
[VS (repr (Value repr))] -> Reader DrasilState (VS (repr (Value repr)))
Expand Down
53 changes: 38 additions & 15 deletions code/drasil-code/Language/Drasil/Code/Imperative/Generator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,39 @@ module Language.Drasil.Code.Imperative.Generator (

import Language.Drasil
import Language.Drasil.Code.Imperative.ConceptMatch (chooseConcept)
import Language.Drasil.Code.Imperative.GenerateGOOL (genDoxConfig)
import Language.Drasil.Code.Imperative.Import (genModDef)
import Language.Drasil.Code.Imperative.Modules (chooseInModule, genConstMod,
genMain, genOutputMod, genSampleInput)
import Language.Drasil.Code.Imperative.State (DrasilState(..))
import Language.Drasil.Code.Imperative.GenerateGOOL (genDoxConfig, genModule)
import Language.Drasil.Code.Imperative.Helpers (liftS)
import Language.Drasil.Code.Imperative.Import (genModDef, genModFuncs)
import Language.Drasil.Code.Imperative.Modules (chooseInModule, genConstClass,
genConstMod, genInputClass, genInputConstraints, genInputDerived,
genInputFormat, genMain, genMainFunc, genOutputFormat, genOutputMod,
genSampleInput)
import Language.Drasil.Code.Imperative.DrasilState (DrasilState(..), inMod)
import Language.Drasil.Code.Imperative.GOOL.Symantics (PackageSym(..),
AuxiliarySym(..))
import Language.Drasil.Code.Imperative.GOOL.Data (PackData(..))
import Language.Drasil.Code.CodeGeneration (createCodeFiles, makeCode)
import Language.Drasil.Chunk.Code (programName)
import Language.Drasil.CodeSpec (CodeSpec(..), CodeSystInfo(..), Choices(..),
Lang(..), Visibility(..))
Lang(..), Modularity(..), Visibility(..))

import GOOL.Drasil (ProgramSym(..), ProgramSym, FileSym(..), ProgData(..),
GS, FS, initialState, unCI)
import GOOL.Drasil (ProgramSym(..), ProgramSym, FileSym(..), ScopeTag(..),
ProgData(..), GS, FS, initialState, unCI)

import System.Directory (setCurrentDirectory, createDirectoryIfMissing,
getCurrentDirectory)
import Control.Monad.Reader (Reader, ask, runReader)
import Control.Monad.State (evalState, runState)
import Data.Map (member)

generator :: String -> [Expr] -> Choices -> CodeSpec -> DrasilState
generator dt sd chs spec = DrasilState {
-- constants
codeSpec = spec,
date = showDate $ dates chs,
modular = modularity chs,
inStruct = inputStructure chs,
conStruct = constStructure chs,
conRepr = constRepr chs,
inMod = inputModule chs,
logKind = logging chs,
commented = comments chs,
doxOutput = doxVerbosity chs,
Expand All @@ -42,6 +45,7 @@ generator dt sd chs spec = DrasilState {
sampleData = sd,
-- state
currentModule = "",
currentClass = "",

-- next depend on chs
logName = logFile chs,
Expand Down Expand Up @@ -74,7 +78,7 @@ genPackage unRepr = do
let info = unCI $ evalState ci initialState
(reprPD, s) = runState p info
pd = unRepr reprPD
n = case codeSpec g of CodeSpec {program = pr} -> programName pr
n = pName $ csi $ codeSpec g
m = makefile (commented g) s pd
i <- genSampleInput
d <- genDoxConfig n s
Expand All @@ -83,12 +87,31 @@ genPackage unRepr = do
genProgram :: (ProgramSym repr) => Reader DrasilState (GS (repr (Program repr)))
genProgram = do
g <- ask
ms <- genModules
-- Below line of code cannot be simplified because program has a generic type
let n = case codeSpec g of CodeSpec {program = p} -> programName p
ms <- chooseModules $ modular g
let n = pName $ csi $ codeSpec g
return $ prog n ms

chooseModules :: (ProgramSym repr) => Modularity ->
Reader DrasilState [FS (repr (RenderFile repr))]
chooseModules Unmodular = liftS genUnmodular
chooseModules (Modular _) = genModules

genUnmodular :: (ProgramSym repr) =>
Reader DrasilState (FS (repr (RenderFile repr)))
genUnmodular = do
g <- ask
let s = csi $ codeSpec g
n = pName $ csi $ codeSpec g
cls = any (`member` clsMap (codeSpec g))
["get_input", "derived_values", "input_constraints"]
genModule n ("Contains the entire " ++ n ++ " program")
(map (fmap Just) (genMainFunc : concatMap genModFuncs (mods s)) ++
((if cls then [] else [genInputFormat Pub, genInputDerived Pub,
genInputConstraints Pub]) ++ [genOutputFormat]))
[genInputClass Priv, genConstClass Priv]

genModules :: (ProgramSym repr) => Reader DrasilState [FS (repr (RenderFile repr))]
genModules :: (ProgramSym repr) =>
Reader DrasilState [FS (repr (RenderFile repr))]
genModules = do
g <- ask
let s = csi $ codeSpec g
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Language.Drasil.Code.Imperative.Helpers (

import Language.Drasil
import Database.Drasil (symbResolve)
import Language.Drasil.Code.Imperative.State (DrasilState(..))
import Language.Drasil.Code.Imperative.DrasilState (DrasilState(..))
import Language.Drasil.CodeSpec (CodeSpec(..), CodeSystInfo(..))

import Control.Monad.Reader (Reader)
Expand Down
Loading