OpDiv (OperatorExpr num terminal) (OperatorExpr num terminal) |
OpPow (OperatorExpr num terminal) (OperatorExpr num terminal) |
OpNeg (OperatorExpr num terminal) |
+ OpIndexedScalarIdentifier String [String] |
OpConstant num |
OpTerminal terminal
deriving Show
OpDiv a b -> binaryToDoc "/" a b
OpPow a b -> binaryToDoc "^" a b
OpNeg o -> hcat [text "(-", toDoc o, text ")"]
+ OpIndexedScalarIdentifier name indices -> text name <> case indices of
+ [] -> empty
+ nonNil -> brackets $ hcat $ punctuate comma (map text nonNil)
OpConstant c -> toDoc c
OpTerminal t -> toDoc t
where
Neg :: Expression e -> Expression e
MulScalar :: Expression e -> Expression ScalarE -> Expression e
DivScalar :: Expression e -> Expression ScalarE -> Expression e
+ Power :: Expression ScalarE -> Expression ScalarE -> Expression ScalarE
PsincProduct :: Expression PsincE -> Expression PsincE -> Expression PsincE
PsincReciprocalProduct :: Expression PsincReciprocalE -> Expression PsincReciprocalE -> Expression PsincReciprocalE
ConstInteger :: Integer -> Expression ScalarE
AnalyticMomentum e -> text "momentum_operator" <> (parens $ toDoc e)
MulScalar a b -> binaryToDoc "*" a b
DivScalar a b -> binaryToDoc "/" a b
+ Power a b -> binaryToDoc "^" a b
PsincProduct a b -> binaryToDoc "*" a b
PsincReciprocalProduct a b -> binaryToDoc "*" a b
where
TopLevel.IntegerType -> buildScalarAssign
TopLevel.RealType -> buildScalarAssign
TopLevel.FunctionType -> buildFieldAssign
- where buildScalarAssign = AssignScalar (buildScalarExpression ofl ofl2 lhs) (buildScalarExpression ofl ofl2 rhs)
- buildFieldAssign = AssignPsinc (buildPsincExpression ofl ofl2 lhs) (buildPsincExpression ofl ofl2 rhs)
+ where buildScalarAssign = AssignScalar (buildScalarExpression' lhs) (buildScalarExpression' rhs)
+ buildFieldAssign = AssignPsinc (buildPsincExpression' lhs) (buildPsincExpression' rhs)
+ buildScalarExpression' = buildScalarExpression ofl ofl2
+ buildPsincExpression' = buildPsincExpression ofl ofl2
buildScalarExpression :: OFL -> OFL2 -> TopLevel.Expression -> Expression ScalarE
-buildScalarExpression _ _ e = error $ "Unimplemented scalar expression: " ++ prettyPrint e
+buildScalarExpression _ _ (TopLevel.IndexedIdentifier name indices) = IndexedScalarIdentifier name indices
+buildScalarExpression _ _ (TopLevel.ConstReal r) = ConstReal r
+buildScalarExpression _ _ (TopLevel.ConstInteger i) = ConstInteger i
+buildScalarExpression ofl ofl2 (TopLevel.Negate e) = Neg $ buildScalarExpression ofl ofl2 e
+buildScalarExpression ofl ofl2 (TopLevel.Integrate e) = Integrate $ buildPsincExpression ofl ofl2 e
+buildScalarExpression ofl ofl2 (TopLevel.Sum e index) = Sum (buildScalarExpression ofl ofl2 e) index
+buildScalarExpression ofl ofl2 (TopLevel.Multiply a b) = MulScalar a' b' where
+ a' = (buildScalarExpression ofl ofl2 a)
+ b' = (buildScalarExpression ofl ofl2 b)
+buildScalarExpression ofl ofl2 (TopLevel.Divide a b) = DivScalar a' b' where
+ a' = (buildScalarExpression ofl ofl2 a)
+ b' = (buildScalarExpression ofl ofl2 b)
+buildScalarExpression ofl ofl2 (TopLevel.Add a b) = Add a' b' where
+ a' = (buildScalarExpression ofl ofl2 a)
+ b' = (buildScalarExpression ofl ofl2 b)
+buildScalarExpression ofl ofl2 (TopLevel.Sub a b) = Sub a' b' where
+ a' = (buildScalarExpression ofl ofl2 a)
+ b' = (buildScalarExpression ofl ofl2 b)
+buildScalarExpression ofl ofl2 (TopLevel.Power a b) = Power a' b' where
+ a' = (buildScalarExpression ofl ofl2 a)
+ b' = (buildScalarExpression ofl ofl2 b)
+buildScalarExpression _ _ (TopLevel.PositionComponent index) =
+ error $ "Reference to position component " ++ index ++ "should only occur in field expression."
+buildScalarExpression _ _ sd@(TopLevel.SpatialDerivative _ _ _) =
+ error $ "Reference to spatial derivative " ++ (prettyPrint sd) ++ " should only occur in field expression."
buildPsincExpression :: OFL -> OFL2 -> TopLevel.Expression -> Expression PsincE
-buildPsincExpression _ _ e = error $ "Unimplemented psinc expression: " ++ prettyPrint e
-
--- buildAssignment ofl ofl2 (TopLevel.Assign lhs rhs) =
--- Assign (buildExpression' lhs) (buildExpression' rhs)
--- where
--- buildExpression' = buildExpression ofl ofl2
---
--- buildExpression :: OFL -> OFL2 -> TopLevel.Expression -> Expression
--- buildExpression _ _ (TopLevel.IndexedIdentifier name indices) = IndexedIdentifier name indices
--- buildExpression _ _ (TopLevel.ConstReal r) = ConstReal r
--- buildExpression _ _ (TopLevel.ConstInteger i) = ConstInteger i
--- buildExpression ofl ofl2 (TopLevel.Negate e) = Negate $ buildExpression ofl ofl2 e
--- buildExpression ofl ofl2 (TopLevel.Integrate e) = Integrate $ buildExpression ofl ofl2 e
--- buildExpression ofl ofl2 (TopLevel.Sum e index) = Sum (buildExpression ofl ofl2 e) index
--- buildExpression ofl ofl2 (TopLevel.Multiply e1 e2) = Mul (buildExpression ofl ofl2 e1) (buildExpression ofl ofl2 e2)
--- buildExpression ofl ofl2 (TopLevel.Divide e1 e2) = Div (buildExpression ofl ofl2 e1) (buildExpression ofl ofl2 e2)
--- buildExpression ofl ofl2 (TopLevel.Add e1 e2) = Add (buildExpression ofl ofl2 e1) (buildExpression ofl ofl2 e2)
--- buildExpression ofl ofl2 (TopLevel.Sub e1 e2) = Sub (buildExpression ofl ofl2 e1) (buildExpression ofl ofl2 e2)
--- buildExpression ofl ofl2 (TopLevel.Power e1 e2) = Pow (buildExpression ofl ofl2 e1) (buildExpression ofl ofl2 e2)
--- buildExpression _ _ (TopLevel.PositionComponent i) = PositionComponent i
--- buildExpression ofl ofl2 (TopLevel.SpatialDerivative e index n) = Mul operator $ ToMomentum (buildExpression ofl ofl2 e)
--- where
--- operator = Pow derivative (ConstInteger n)
--- derivative = Mul (MomentumComponent index) (ConstComplex $ 0.0 :+ (-1.0))
+buildPsincExpression _ _ (TopLevel.IndexedIdentifier name indices) = IndexedPsincIdentifier name indices
+buildPsincExpression _ _ (TopLevel.ConstReal r) = error $ "Expected a field, found real: " ++ show r
+buildPsincExpression _ _ (TopLevel.ConstInteger i) = error $ "Expected a field, found integer: " ++ show i
+buildPsincExpression ofl ofl2 (TopLevel.Negate e) = Neg $ buildPsincExpression ofl ofl2 e
+buildPsincExpression _ _ (TopLevel.Integrate e) =
+ error $ "Expected field-dependent expression for integration: " ++ prettyPrint e
+buildPsincExpression ofl ofl2 (TopLevel.Sum e index) = Sum (buildPsincExpression ofl ofl2 e) index
+buildPsincExpression ofl ofl2 (TopLevel.Multiply a b) = buildPsincMultiplyExpression ofl ofl2 a b
+buildPsincExpression ofl ofl2 (TopLevel.Divide a b) = DivScalar a' b' where
+ a' = buildPsincExpression ofl ofl2 a
+ b' = buildScalarExpression ofl ofl2 b
+buildPsincExpression ofl ofl2 (TopLevel.Add a b) = Add a' b' where
+ a' = buildPsincExpression ofl ofl2 a
+ b' = buildPsincExpression ofl ofl2 b
+buildPsincExpression ofl ofl2 (TopLevel.Sub a b) = Sub a' b' where
+ a' = buildPsincExpression ofl ofl2 a
+ b' = buildPsincExpression ofl ofl2 b
+buildPsincExpression ofl ofl2 pc@(TopLevel.PositionComponent _) =
+ AnalyticPosition $ buildPositionOperator ofl ofl2 pc
+buildPsincExpression ofl ofl2 e@(TopLevel.Power _ _) =
+ AnalyticPosition $ buildPositionOperator ofl ofl2 e
+buildPsincExpression ofl ofl2 (TopLevel.SpatialDerivative e index degree) =
+ ToPosition derivativeInMomentumSpace
+ where
+ derivativeInMomentumSpace =
+ PsincReciprocalProduct operandInMomentumSpace (AnalyticMomentum raisedDerivativeOperator)
+ operandInMomentumSpace = ToMomentum operand
+ operand = buildPsincExpression ofl ofl2 e
+ raisedDerivativeOperator =
+ derivativeOperator `OpPow` OpConstant (fromInteger degree :+ 0.0)
+ derivativeOperator =
+ (OpTerminal $ MomentumComponent index) `OpMul` (OpConstant $ 0.0 :+ (-1.0))
+
+buildPsincMultiplyExpression :: OFL -> OFL2 -> TopLevel.Expression -> TopLevel.Expression -> Expression PsincE
+buildPsincMultiplyExpression ofl ofl2 e1 e2 = let getGeneralType = TopLevel.baseToGeneralType . TopLevel.getType ofl in
+ case (getGeneralType e1, getGeneralType e2) of
+ (TopLevel.FieldType, TopLevel.FieldType) -> PsincProduct e1AsField e2AsField
+ (TopLevel.FieldType, TopLevel.ScalarType) -> MulScalar e1AsField e2AsScalar
+ (TopLevel.ScalarType, TopLevel.FieldType) -> MulScalar e2AsField e1AsScalar
+ _ -> error $ "Couldn't work out how to evaluate product of " ++
+ (prettyPrint e1) ++ " and " ++ (prettyPrint e2) ++ " as a field."
+ where
+ e1AsField = buildPsincExpression ofl ofl2 e1
+ e2AsField = buildPsincExpression ofl ofl2 e2
+ e1AsScalar = buildScalarExpression ofl ofl2 e1
+ e2AsScalar = buildScalarExpression ofl ofl2 e2
+
+buildPositionOperator :: OFL -> OFL2 -> TopLevel.Expression -> OperatorExpr Double PositionTerminal
+buildPositionOperator _ _ (TopLevel.ConstReal r) = OpConstant r
+buildPositionOperator _ _ (TopLevel.ConstInteger i) = OpConstant $ fromInteger i
+buildPositionOperator ofl ofl2 (TopLevel.Power a b) = (buildPositionOperator ofl ofl2 a) `OpPow` (buildPositionOperator ofl ofl2 b)
+buildPositionOperator _ _ (TopLevel.IndexedIdentifier name indices) = OpIndexedScalarIdentifier name indices
+buildPositionOperator _ _ (TopLevel.PositionComponent index) = OpTerminal $ PositionComponent index
+buildPositionOperator _ _ e = error $ "Unhandled expression: " ++ prettyPrint e