module Language.Fortran.Intrinsics
( getVersionIntrinsics, getIntrinsicReturnType, getIntrinsicNames, getIntrinsicDefsUses, isIntrinsic
, IntrinsicType(..), IntrinsicsTable, allIntrinsics )
where
import qualified Data.Map.Strict as M
import Data.Data
import Data.List
import GHC.Generics (Generic)
import Language.Fortran.ParserMonad (FortranVersion(..))
data IntrinsicType = ITReal | ITInteger | ITComplex | ITDouble | ITLogical | ITParam Int
deriving (Show, Eq, Ord, Typeable, Generic)
data IntrinsicsEntry = IEntry { iType :: IntrinsicType, iDefsUses :: ([Int], [Int]) }
deriving (Show, Eq, Ord, Typeable, Generic)
mkIEntry ty du = IEntry ty du
type IntrinsicsTable = M.Map String IntrinsicsEntry
fortranVersionIntrinsics =
[ (Fortran66, fortran77intrinsics)
, (Fortran77, fortran77intrinsics)
, (Fortran90, fortran90intrinisics) ]
getVersionIntrinsics :: FortranVersion -> IntrinsicsTable
getVersionIntrinsics v = snd . last . filter ((<= v) . fst) . sort $ fortranVersionIntrinsics
getIntrinsicReturnType :: String -> IntrinsicsTable -> Maybe IntrinsicType
getIntrinsicReturnType i = fmap iType . M.lookup i
getIntrinsicDefsUses :: String -> IntrinsicsTable -> Maybe ([Int], [Int])
getIntrinsicDefsUses i = fmap iDefsUses . M.lookup i
getIntrinsicNames :: IntrinsicsTable -> [String]
getIntrinsicNames = M.keys
isIntrinsic :: String -> IntrinsicsTable -> Bool
isIntrinsic = M.member
allIntrinsics :: IntrinsicsTable
allIntrinsics = M.unions (map snd fortranVersionIntrinsics)
func1 = ([0],[1])
func2 = ([0],[1,2])
func3 = ([0],[1,2,3])
funcN = func2
fortran77intrinsics :: IntrinsicsTable
fortran77intrinsics = M.fromList
[ ("abs" , mkIEntry (ITParam 1) func1)
, ("aimag" , mkIEntry (ITReal) func1)
, ("aint" , mkIEntry (ITReal) func1)
, ("anint" , mkIEntry (ITReal) func1)
, ("cmplx" , mkIEntry (ITComplex) func1)
, ("conjg" , mkIEntry (ITComplex) func1)
, ("dble" , mkIEntry (ITDouble) func1)
, ("dim" , mkIEntry (ITReal) func1)
, ("dprod" , mkIEntry (ITDouble) func1)
, ("int" , mkIEntry (ITInteger) func1)
, ("max" , mkIEntry (ITParam 1) funcN)
, ("min" , mkIEntry (ITParam 1) funcN)
, ("mod" , mkIEntry (ITParam 1) func2)
, ("nint" , mkIEntry (ITInteger) func1)
, ("real" , mkIEntry (ITReal) func1)
, ("sign" , mkIEntry (ITParam 1) func2)
]
fortran90intrinisics :: IntrinsicsTable
fortran90intrinisics = fortran77intrinsics `M.union` M.fromList
[ ("iabs" , mkIEntry (ITInteger) func1)
, ("dabs" , mkIEntry (ITDouble) func1)
, ("cabs" , mkIEntry (ITComplex) func1)
, ("dint" , mkIEntry (ITDouble) func1)
, ("dnint" , mkIEntry (ITDouble) func1)
, ("idnint" , mkIEntry (ITInteger) func1)
, ("ifix" , mkIEntry (ITInteger) func1)
, ("idint" , mkIEntry (ITInteger) func1)
, ("min0" , mkIEntry (ITInteger) funcN)
, ("amin1" , mkIEntry (ITReal) funcN)
, ("dmin1" , mkIEntry (ITDouble) funcN)
, ("amin0" , mkIEntry (ITReal) funcN)
, ("min1" , mkIEntry (ITInteger) funcN)
, ("amod" , mkIEntry (ITReal) func2)
, ("dmod" , mkIEntry (ITDouble) func2)
, ("float" , mkIEntry (ITReal) func1)
, ("sngl" , mkIEntry (ITReal) func1)
, ("isign" , mkIEntry (ITInteger) func2)
, ("dsign" , mkIEntry (ITDouble) func2)
, ("present" , mkIEntry (ITLogical) func1)
, ("sqrt" , mkIEntry (ITParam 1) func1)
, ("dsqrt" , mkIEntry (ITDouble) func1)
, ("csqrt" , mkIEntry (ITComplex) func1)
, ("exp" , mkIEntry (ITParam 1) func1)
, ("dexp" , mkIEntry (ITDouble) func1)
, ("cexp" , mkIEntry (ITComplex) func1)
, ("log" , mkIEntry (ITParam 1) func1)
, ("alog" , mkIEntry (ITReal) func1)
, ("dlog" , mkIEntry (ITDouble) func1)
, ("clog" , mkIEntry (ITComplex) func1)
, ("log10" , mkIEntry (ITParam 1) func1)
, ("alog10" , mkIEntry (ITReal) func1)
, ("dlog10" , mkIEntry (ITDouble) func1)
, ("idim" , mkIEntry (ITInteger) func2)
, ("ddim" , mkIEntry (ITDouble) func2)
, ("sin" , mkIEntry (ITReal) func1)
, ("dsin" , mkIEntry (ITDouble) func1)
, ("csin" , mkIEntry (ITComplex) func1)
, ("cos" , mkIEntry (ITReal) func1)
, ("dcos" , mkIEntry (ITDouble) func1)
, ("ccos" , mkIEntry (ITComplex) func1)
, ("tan" , mkIEntry (ITReal) func1)
, ("dtan" , mkIEntry (ITDouble) func1)
, ("asin" , mkIEntry (ITReal) func1)
, ("dasin" , mkIEntry (ITDouble) func1)
, ("acos" , mkIEntry (ITReal) func1)
, ("dacos" , mkIEntry (ITDouble) func1)
, ("atan" , mkIEntry (ITReal) func1)
, ("datan" , mkIEntry (ITDouble) func1)
, ("atan2" , mkIEntry (ITReal) func2)
, ("datan2" , mkIEntry (ITDouble) func2)
, ("sinh" , mkIEntry (ITReal) func1)
, ("dsinh" , mkIEntry (ITDouble) func1)
, ("cosh" , mkIEntry (ITReal) func1)
, ("dcosh" , mkIEntry (ITDouble) func1)
, ("tanh" , mkIEntry (ITReal) func1)
, ("dtanh" , mkIEntry (ITDouble) func1)
, ("modulo" , mkIEntry (ITParam 1) func2)
, ("ceiling" , mkIEntry (ITParam 1) func1)
, ("floor" , mkIEntry (ITParam 1) func1)
, ("iand" , mkIEntry (ITInteger) func2)
, ("ior" , mkIEntry (ITInteger) func2)
, ("ieor" , mkIEntry (ITInteger) func2)
, ("iany" , mkIEntry (ITInteger) func2)
, ("ibclr" , mkIEntry (ITInteger) func2)
, ("ibits" , mkIEntry (ITInteger) func3)
, ("ibset" , mkIEntry (ITInteger) func2)
, ("ishftc" , mkIEntry (ITInteger) func3)
, ("btest" , mkIEntry (ITInteger) func2)
, ("not" , mkIEntry (ITInteger) func1)
]