fortran-vars-0.3.1: src/Language/Fortran/Vars/PureExpression.hs
module Language.Fortran.Vars.PureExpression
( isPureExpression
)
where
import Data.Maybe ( catMaybes )
import Language.Fortran.AST ( Expression(..)
, Index(..)
, Value(..)
, aStrip
)
import Language.Fortran.AST.Literal.Complex
( ComplexLit(..)
, ComplexPart(..)
)
import Language.Fortran.Vars.Call
( functionArguments )
-- | Given an 'Expression', determine whether it is a pure expression.
-- A pure expression does not have side effect.
-- return true if the expression is guaranteed to be pure,
-- return false if the expression can not be guaranteed to be pure.
isPureExpression :: Expression a -> Bool
isPureExpression (ExpValue _ _ v) = isPureValue v
isPureExpression (ExpBinary _ _ _ e1 e2) =
isPureExpression e1 && isPureExpression e2
isPureExpression (ExpUnary _ _ _ e) = isPureExpression e
isPureExpression (ExpSubscript _ _ _ indices) =
all isPureIndex (aStrip indices)
isPureExpression e@ExpFunctionCall{} =
isIntrinsicFunctionCall e && all isPureExpression (functionArguments e)
isPureExpression (ExpInitialisation _ _ exprs) =
all isPureExpression (aStrip exprs)
isPureExpression ExpReturnSpec{} = False
isPureExpression ExpImpliedDo{} = False
isPureExpression ExpDataRef{} = False
-- | Given a 'Value', determine whether it is pure
isPureValue :: Value a -> Bool
isPureValue ValInteger{} = True
isPureValue ValReal{} = True
isPureValue (ValComplex c) = complexLitIsPure c
isPureValue ValString{} = True
isPureValue ValHollerith{} = True
isPureValue ValVariable{} = True
isPureValue ValIntrinsic{} = True
isPureValue ValLogical{} = True
isPureValue ValStar = True
isPureValue _ = False
-- | Is the given COMPLEX literal "pure", i.e. does it have no named constant
-- components?
complexLitIsPure :: ComplexLit a -> Bool
complexLitIsPure c =
check (complexLitRealPart c) && check (complexLitImagPart c)
where check = \case ComplexPartNamed{} -> False
_ -> True
-- | Given an 'Index', determine whether it is pure
isPureIndex :: Index a -> Bool
isPureIndex (IxSingle _ _ _ e) = isPureExpression e
isPureIndex (IxRange _ _ me1 me2 me3) =
all isPureExpression $ catMaybes [me1, me2, me3]
-- | Given an expression determine whether it is intrinsic function call
isIntrinsicFunctionCall :: Expression a -> Bool
isIntrinsicFunctionCall (ExpFunctionCall _ _ (ExpValue _ _ (ValIntrinsic _)) _)
= True
isIntrinsicFunctionCall _ = False