module Camfort.Helpers.Syntax where
import Data.Char
import Data.List
import Data.Monoid
import Control.Monad.State.Lazy
import Debug.Trace
import Data.Data
import Data.Generics.Uniplate.Data
import Data.Generics.Uniplate.Operations
import Data.Generics.Zipper
import Data.Typeable
import Camfort.Analysis.Annotations
import qualified Language.Fortran.AST as F
import qualified Language.Fortran.Util.Position as FU
import Language.Fortran.Util.FirstParameter
import Language.Fortran.Util.SecondParameter
data AnnotationFree t = AnnotationFree { annotationBound :: t } deriving Show
af = AnnotationFree
unaf = annotationBound
caml (x:xs) = toUpper x : xs
lower = map toLower
instance Eq (AnnotationFree a) => Eq (AnnotationFree [a]) where
(AnnotationFree xs) == (AnnotationFree xs') =
if length xs == length xs'
then foldl (\b (x, x') -> (af x == af x') && b) True (zip xs xs')
else False
instance (Eq (AnnotationFree a), Eq (AnnotationFree b))
=> Eq (AnnotationFree (a, b)) where
(AnnotationFree (x, y)) == (AnnotationFree (x', y')) =
(af x == af x') && (af y == af y')
instance Eq a => Eq (AnnotationFree (F.Expression a)) where
(AnnotationFree x) == (AnnotationFree y) = x'' == y''
where x' = fmap (const ()) x
y' = fmap (const ()) y
y'' = transformBi setSpanConst y'
x'' = transformBi setSpanConst x'
setSpanConst :: FU.SrcSpan -> FU.SrcSpan
setSpanConst (FU.SrcSpan _ _) = FU.SrcSpan pos0 pos0
where pos0 = FU.Position 0 0 0
instance Eq (AnnotationFree F.BaseType) where
(AnnotationFree x) == (AnnotationFree y) = x == y
extractVariable :: F.Expression a -> Maybe F.Name
extractVariable (F.ExpValue _ _ (F.ValVariable v)) = Just v
extractVariable (F.ExpSubscript _ _ e _) = extractVariable e
extractVariable _ = Nothing
instance Monoid Int where
mempty = 0
mappend = (+)
dropLine :: FU.SrcSpan -> FU.SrcSpan
dropLine (FU.SrcSpan s1 (FU.Position o c l)) =
FU.SrcSpan s1 (FU.Position o 0 (l+1))
deleteLine :: FU.SrcSpan -> FU.SrcSpan
deleteLine (FU.SrcSpan (FU.Position ol cl ll) (FU.Position ou cu lu)) =
FU.SrcSpan (FU.Position ol (cl1) ll) (FU.Position ou 0 (lu+1))
linesCovered :: FU.Position -> FU.Position -> Int
linesCovered (FU.Position _ _ l1) (FU.Position _ _ l2) = l2 l1 + 1
toCol0 (FU.Position o c l) = FU.Position o 0 l
afterAligned :: FU.SrcSpan -> FU.Position
afterAligned (FU.SrcSpan (FU.Position o cA lA) (FU.Position _ cB lB)) =
FU.Position o cA (lB+1)