import TopLevel
import TargetMapping
import Data.List (foldl1')
+import Data.Functor.Identity (Identity)
import Text.Parsec
import Text.Parsec.Expr
import Text.Parsec.Token
map show [minBound::BaseType ..] ++
["^", "+", "-", "*", "/", "=", "laplacian", "inner", "sum", "derivative", "r", "target"]
+oflDef :: LanguageDef st
oflDef = emptyDef {
commentStart = "",
commentEnd = "",
stringLiteral = lStringLiteral
} = makeTokenParser oflDef
+oflOperatorTable :: OperatorTable String st Identity Expression
oflOperatorTable = [[Infix (do _ <- lSymbol "^"; return Power) AssocLeft],
[Prefix (do _ <- lSymbol "-"; return Negate)],
[Infix (do _ <- lSymbol "*"; return Multiply) AssocLeft
,Infix (do _ <- lSymbol "-"; return Sub) AssocLeft]
]
+type OFLParser a = Parsec String OFL a
+
+parseType :: OFLParser BaseType
parseType = foldl1' (<|>) [do lReserved $ toOFLString t; return t | t <- [minBound::BaseType ..]]
+
+parseIndex :: OFLParser IndexType
parseIndex = foldl1' (<|>) [do lReserved $ toOFLString t; return t | t <- [minBound::IndexType ..]]
-parseDeclaration :: Parsec String OFL ()
+parseDeclaration :: OFLParser ()
parseDeclaration = parseValueDeclaration <|> parseIndexDeclaration <?> "declaration"
-parseValueDeclaration :: Parsec String OFL ()
+parseValueDeclaration :: OFLParser ()
parseValueDeclaration = do
valueType <- parseType
indices <- option [] (lBrackets $ lCommaSep parseIndex)
sequence_ [modifyState(\x -> addValueDeclaration x name valueType indices) | name <- names]
<?> "value declaration"
-parseIndexDeclaration :: Parsec String OFL ()
+parseIndexDeclaration :: OFLParser ()
parseIndexDeclaration = do
indexType <- parseIndex
names <- lCommaSep1 parseIdentifier
sequence_ [modifyState(\x -> addIndexDeclaration x name indexType) | name <- names]
<?> "index declaration"
+parseIdentifier :: OFLParser String
parseIdentifier = lIdentifier <?> "identifier"
-parseAssignment :: Parsec String OFL ()
+parseAssignment :: OFLParser ()
parseAssignment = do
lhs <- parseExpression
_ <- lSymbol "="
rhs <- parseExpression
modifyState(\x -> addAssignment x lhs rhs)
<?> "assignment"
-
+
+parseExpression :: OFLParser Expression
parseExpression = buildExpressionParser oflOperatorTable parseTerm <?> "expression"
+parseTerm :: OFLParser Expression
parseTerm =
parseLaplacian
<|> do lReserved "inner"; res <- lParens parseInner; return res
<|> parseIdentifierAccess
<?> "term"
+parseLaplacian :: OFLParser Expression
parseLaplacian = do
lReserved "laplacian";
operand <- lParens parseExpression;
putState ofl';
return $ Sum secondDerivative indexName
+parseInner :: OFLParser Expression
parseInner = do
e1 <- parseExpression
_ <- lSymbol ","
return $ Integrate $ Multiply e1 e2
<?> "inner product"
+parseSum :: OFLParser Expression
parseSum = do
e1 <- parseExpression
_ <- lSymbol ","
return $ Sum e1 index
<?> "sum"
+parseDerivative :: OFLParser Expression
parseDerivative = do
e1 <- parseExpression
_ <- lSymbol ","
return $ SpatialDerivative e1 index 1
<?> "derivative"
+parseIdentifierAccess :: OFLParser Expression
parseIdentifierAccess = do
ident <- parseIdentifier
indices <- option [] (lBrackets $ lCommaSep parseIdentifier)
return $ IndexedIdentifier ident indices
<?> "indexed identifier"
+parseTarget :: OFLParser String
parseTarget = do
lReserved "target"
lSymbol "ONETEP"
-parseOFL :: Parsec String OFL OFL
+parseOFL :: OFLParser OFL
parseOFL = do
lWhiteSpace
_ <- many1 parseDeclaration
eof
getState
+parseOutputFunction :: OFLParser ()
parseOutputFunction = do
_ <- lSymbol "OutputFunction"
ident <- parseIdentifier
modifyState(\x -> setOutputFunction x $ FortranFunction ident properties)
<?> "output function specification"
+parseFortranFunctionProperty :: OFLParser FortranFunctionProperty
parseFortranFunctionProperty = do
parseFortranFunctionNameProperty <|> parseFortranFunctionParamsProperty
where
idents <- lParens $ lCommaSep lIdentifier
return $ FortranFunctionParams idents
+parseBinding :: OFLParser ()
parseBinding = do
_ <- lSymbol "Variable" <|> lSymbol "Parameter"
ident <- parseIdentifier
targetType <- (parseFortranParam <|> parsePPDFunctionSet)
modifyState(\x -> addTargetMapping x ident targetType)
+parseFortranParam :: OFLParser TargetType
parseFortranParam = do
_ <- lSymbol "fortran_param"
_ <- lSymbol "with"
properties <- lCommaSep parseFortranParamProperty
return $ FortranParameter properties
+parseFortranParamProperty :: OFLParser FortranParameterProperty
parseFortranParamProperty =
parseNameProperty <|> parseTypeProperty <|> parseSpaceProperty <|> parseIndexedProperty <?> "Fortran parameter property" where
parseNameProperty = do _ <- lSymbol "name"; name <- lParens lStringLiteral; return $ ParamName name
<|> do _ <- lSymbol "psinc_coarse_grid"; indices <- lParens $ lCommaSep1 lIdentifier; return $ CoarsePsinc indices
parseIndexedProperty = do _ <- lSymbol "indexed"; indices <- lParens $ lCommaSep1 lIdentifier; return $ Indexed indices
+parseFortranType :: OFLParser FortranType
parseFortranType = do
baseType <- parseBaseType;
maybeIndices <- optionMaybe parseArrayIndices
<|> do _ <- lSymbol "double"; return Double
<|> do _ <- lSymbol "func_basis"; return FunctionBasis
+parsePPDFunctionSet :: OFLParser TargetType
parsePPDFunctionSet = do
_ <- lSymbol "ppd_function_set"
_ <- lSymbol "with"
properties <- lCommaSep parsePPDFunctionSetProperty
return $ PPDFunctionSet properties
+parsePPDFunctionSetProperty :: OFLParser PPDFunctionSetProperty
parsePPDFunctionSetProperty =
parseBasisProperty <|> parseDataProperty <?> "PPD function set property" where
parseBasisProperty = do _ <- lSymbol "basis"; ident <- lParens lIdentifier; return $ PPDBasis ident