fortran-vars-0.1.0: src/Language/Fortran/Vars/Utils.hs
module Language.Fortran.Vars.Utils where
import Language.Fortran.Analysis ( Analysis )
import Language.Fortran.AST
import Language.Fortran.Vars.Types
( SymbolTable
, ExpVal(..)
, Type(..)
, SemType(..)
)
import Language.Fortran.Vars.Eval
( eval
, eval'
)
import Language.Fortran.Vars.Kind
( setTypeKind
, kindOfBaseType
, baseToType
)
-- | Given dimenion declarators and the typespec, give ArrayTypeData evaluating
-- valid expressions for the upper and lower bound
typeSpecToArrayType
:: SymbolTable
-> [DimensionDeclarator (Analysis a)]
-> TypeSpec (Analysis a)
-> Type
typeSpecToArrayType st dims tySpec = TArray scalarTy $ Just $ map dimStrip dims
where
scalarTy = typeSpecToScalarType st tySpec
dimStrip (DimensionDeclarator _ _ (Just lb) (Just ub)) =
(constInt lb, constInt ub)
dimStrip (DimensionDeclarator _ _ Nothing (Just ub)) = (1, constInt ub)
dimStrip _ = error "Invalid dimension declarator"
constInt x = case eval st x of
Int y -> y
_ -> error "Invalid array spec"
-- | Given the typespec of a scalar get the StaticType
typeSpecToScalarType :: SymbolTable -> TypeSpec (Analysis a) -> Type
typeSpecToScalarType st (TypeSpec _ _ ty selector) =
let ty' = baseToType ty
in case selector of
Just (Selector _ _ _ (Just k)) -> setTypeKind ty' (constInt k)
Just (Selector _ _ (Just l) _ ) -> setTypeKind ty' (constInt l)
Nothing -> setTypeKind ty' (Just $ kindOfBaseType ty)
_ -> error "Invalid type spec"
where
constInt x = case eval' st x of
Right (Int y) -> Just y
_ -> Nothing