parseExpression = buildExpressionParser oflOperatorTable parseTerm <?> "expression"
-parseTerm = do
- lReserved "laplacian"; operand <- lParens parseExpression; return $ Laplacian operand
+parseTerm =
+ parseLaplacian
<|> do lReserved "inner"; res <- lParens parseInner; return res
<|> do lReserved "sum"; res <- lParens parseSum; return res
<|> do lReserved "derivative"; res <- lParens parseDerivative; return res
<|> lParens parseExpression
<|> parseIdentifierAccess
<?> "term"
+
+parseLaplacian = do
+ lReserved "laplacian";
+ operand <- lParens parseExpression;
+ ofl <- getState
+ let
+ indexName = findUniqueName ofl "laplacian"
+ secondDerivative = SpatialDerivative operand indexName 2
+ ofl' = addIndexDeclaration ofl indexName SpatialIndex in
+ do
+ putState ofl';
+ return $ Sum secondDerivative indexName
parseInner = do
e1 <- parseExpression
e1 <- parseExpression
_ <- lSymbol ","
index <- parseIdentifier
- return $ Derivative e1 index
+ return $ SpatialDerivative e1 index 1
<?> "derivative"
parseIdentifierAccess = do
ConstInteger Integer |
Negate Expression |
Integrate Expression |
- Laplacian Expression |
Sum Expression String |
Multiply Expression Expression |
Divide Expression Expression |
Sub Expression Expression |
Power Expression Expression |
PositionComponent String |
- Derivative Expression String
+ SpatialDerivative Expression String Integer
deriving Show
-
+
data Assignment = Assign Expression Expression deriving Show
class OFLKeyword a where
addIndexDeclaration ofl name indexType = ofl { symbols = symbols' }
where symbols' = insertWithKey errorOnDuplicate name (IndexTag indexType) (symbols ofl)
+findUniqueName :: OFL -> String -> String
+findUniqueName ofl candidate = head [n | n <- generateSuffixed, not $ hasSymbol ofl n]
+ where generateSuffixed = [candidate ++ "_" ++ show n | n <- [1::Integer ..]]
+
addAssignment :: OFL -> Expression -> Expression -> OFL
addAssignment ofl lhs rhs =
let assignment = (Assign lhs rhs) in
Just (IndexTag _) -> True
_ -> False
+hasSymbol :: OFL -> String -> Bool
+hasSymbol ofl name = case Map.lookup name (symbols ofl) of
+ Just _ -> True
+ _ -> False
+
hasValue :: OFL -> String -> Bool
hasValue ofl name = case Map.lookup name (symbols ofl) of
Just (ValueTag _ _) -> True
getType _ (ConstReal _) = RealType
getType _ (ConstInteger _) = IntegerType
getType _ (Integrate _) = RealType
-getType _ (Laplacian _) = FunctionType
getType _ (PositionComponent _) = FunctionType
getType ofl (IndexedIdentifier name _) = getValueType ofl name
getType ofl (Negate e) = getType ofl e
getType ofl (Add a b) = promoteType (getType ofl a) (getType ofl b)
getType ofl (Sub a b) = promoteType (getType ofl a) (getType ofl b)
getType ofl (Power a b) = promoteType (getType ofl a) (getType ofl b)
-getType ofl (Derivative e _) = getType ofl e
+getType ofl (SpatialDerivative e _ _) = getType ofl e
emptyOFL :: OFL
emptyOFL = OFL {
validateExpression ofl a
isFunction ofl a
-validateExpression ofl (Laplacian e) = do
- validateExpression ofl e
- isFunction ofl e
-
validateExpression ofl (Sum e i) = do
validateExpression ofl e
indexExists ofl i
indexExists ofl i
indexIsType ofl i SpatialIndex
-validateExpression ofl (Derivative e i) = do
+validateExpression ofl (SpatialDerivative e d _) = do
validateExpression ofl e
- indexExists ofl i
- indexIsType ofl i SpatialIndex
+ indexExists ofl d
+ indexIsType ofl d SpatialIndex