fortran-vars-0.4.0: src/Language/Fortran/Vars/Eval/FortranSrc/Translate.hs
{- | Translate fortran-vars Fortran types and values to fortran-src
(Language.Fortran.Repr).
TODO
* BYTE is apparently LOGICAL(1). Or INTEGER(1) (same thing?). Could make a
special check for that.
-}
module Language.Fortran.Vars.Eval.FortranSrc.Translate where
import qualified Language.Fortran.Vars.Rep as FV
import qualified Language.Fortran.AST.Literal.Boz as AST
import Language.Fortran.Repr
import Language.Fortran.Repr.Type.Array
import GHC.Float ( float2Double )
import qualified Data.Text as Text
import qualified Data.List.NonEmpty as NonEmpty
translateFType :: FType -> FV.SemType
translateFType = \case
MkFScalarType fsty -> translateFScalarType fsty
MkFArrayType fat -> translateFArrayType fat
translateFScalarType :: FScalarType -> FV.SemType
translateFScalarType = \case
FSTInt ftint -> kinded FV.TInteger ftint
FSTReal ftreal -> kinded FV.TReal ftreal
FSTComplex ftreal -> kinded FV.TComplex (FTComplexWrapper ftreal)
FSTLogical ftint -> kinded FV.TInteger ftint
--FSTLogical ftint -> kinded FV.TLogical ftint
FSTString n -> FV.TCharacter (FV.CharLenInt (fromIntegral n)) 1
FSTCustom ty -> FV.TCustom ty
where kinded f = f . translateFKind . printFKind
translateFArrayType :: FArrayType -> FV.SemType
translateFArrayType (FArrayType fsty shape) =
FV.TArray (translateFScalarType fsty) (translateShape shape)
translateFKind :: FKindLit -> FV.Kind
translateFKind = fromIntegral
-- | Note that Fortran defaults to 1-indexed arrays.
translateShape :: Shape -> FV.Dimensions
translateShape =
FV.DimsExplicitShape
. NonEmpty.fromList
. map (\ub -> FV.Dim (Just 1) (Just (fromIntegral ub)))
. getShape
--------------------------------------------------------------------------------
translateFValue :: FValue -> Either String FV.ExpVal
translateFValue = \case
MkFScalarValue fsv -> translateFScalarValue fsv
translateFScalarValue :: FScalarValue -> Either String FV.ExpVal
translateFScalarValue = \case
FSVInt fint -> Right $ FV.Int $ fIntUOp fromIntegral fint
FSVReal freal -> Right $ FV.Real $ fRealUOp' float2Double id freal
FSVComplex _fcomplex -> Left "ExpVal doesn't support complex values"
FSVLogical fint -> Right $ FV.Logical $ fLogicalToBool fint
FSVString t -> Right $ FV.Str $ Text.unpack t
--------------------------------------------------------------------------------
translateExpVal :: FV.ExpVal -> FScalarValue
translateExpVal = \case
FV.Int i -> FSVInt $ FInt4 $ fromIntegral i
-- TODO getting some precisions errors, fortran-src over-precise? unsure where
-- coming from, but need to compare using an epsilon
FV.Real r -> FSVReal $ FReal8 r
FV.Str s -> FSVString $ Text.pack s
FV.Logical b -> FSVLogical $ FInt4 $ fLogicalNumericFromBool b
-- TODO fortran-vars always converts BOZs at INTEGER(2)
FV.Boz boz -> FSVInt $ FInt2 $ AST.bozAsTwosComp boz