fortran-vars-0.3.1: src/Language/Fortran/Vars/CommonLayout.hs
module Language.Fortran.Vars.CommonLayout
( getCommonLayout
, getFlagType
)
where
import qualified Data.Map as M
import Language.Fortran.AST ( Name )
import Language.Fortran.Vars.Types
( SymbolTableEntry(..)
, MemoryBlock(..)
, ProgramUnitModel
, StorageClass(..)
, Offset
, Type
, SemType(..)
, CharacterLen(..)
)
data FlagType =
Default
| AlignCommons
| NoAlignCommons
getFlagType :: String -> FlagType
getFlagType "" = Default
getFlagType "falign-commons" = AlignCommons
getFlagType "fno-align-commons" = NoAlignCommons
getFlagType _ = Default
getCommonLayout
:: ProgramUnitModel -> String -> FlagType -> [(Name, Offset, Type)]
getCommonLayout (symbolTable, storageTable) commonArea flagOptions =
generateOffset annotatedVariables
where
annotatedVariables =
map (\x -> (x, getOffset x, getType x)) (getVariables commonArea)
generateOffset list = case flagOptions of
Default -> list
NoAlignCommons -> list
AlignCommons -> getPaddedOffset list 0
getPaddedOffset [] _ = []
getPaddedOffset ((name, offset, variableType) : xs) cumm =
(name, offset + newCumm, variableType) : getPaddedOffset xs newCumm
where
newCumm = if diff > 0 then cumm + size - diff else cumm
diff = (offset + cumm) `mod` size
size = getSize variableType
getSize variable = case variable of
TInteger size -> size
TReal size -> size
TComplex size -> size
TLogical size -> size
TByte size -> size
TCharacter (CharLenInt i) k -> i*k
TCharacter _ _ ->
error "Cannot handle dynamic length TCharacter in common area"
TArray innerType _ -> getSize innerType
TCustom _ -> error "Cannot handle TCustom in common area"
getVariables cmn =
let cmnStorageName = "/" ++ cmn ++ "/"
in case M.lookup cmnStorageName storageTable of
Just memoryBlock | storageClass memoryBlock == Common ->
variables memoryBlock
_ -> []
getOffset variableName = case M.lookup variableName symbolTable of
Just (SVariable _ (_, offset)) -> offset
_ -> error "variable not found in symbolTable"
getType variableName = case M.lookup variableName symbolTable of
Just (SVariable variableType _) -> variableType
_ -> error "variable not found in symbolTable"