module Language.C.Test.GenericAST where
import Data.Generics
import Text.PrettyPrint
import Language.C
data GenAST = GNode Constr [GenAST]
| GNested [GenAST]
| GLeaf GenLeaf
| GIgnore
deriving (Show,Eq)
instance Pretty GenAST where
pretty (GNode constr sub) =
text (show constr) $$ nest 2 (vcat $ map pretty sub)
pretty (GNested sub) =
text "-" $$ (nest 2 $ (vcat $ map pretty sub))
pretty (GLeaf l) = text (show l)
pretty GIgnore = text ""
data GenLeaf = GIdent Ident |
GCharLit Char |
GStringLit String |
GIntConst Integer |
GDoubleConst Double
deriving (Show,Eq,Ord)
mkGenericCAST :: CTranslUnit -> GenAST
mkGenericCAST = toGenericAST . normalizeAST
normalizeAST :: (Data a) => a -> a
normalizeAST = everywhere $ mkT normalizeCompound where
normalizeCompound :: CStat -> CStat
normalizeCompound (CCompound [] [CBlockStmt stmt] _) = stmt
normalizeCompound s = s
toGenericAST :: (Data a) => a -> GenAST
toGenericAST =
mkAstConNode
`extQ` mkAstAttr
`extQ` mkLeaf GIdent
`extQ` mkLeaf GCharLit
`extQ` mkLeaf GStringLit
`extQ` mkLeaf GIntConst
`extQ` mkLeaf GDoubleConst
where
mkAstConNode :: (Data a) => a -> GenAST
mkAstConNode v = GNode (toConstr v) . map simplifyNode . filter ( /= GIgnore) $ gmapQ toGenericAST v
mkAstAttr :: NodeInfo -> GenAST
mkAstAttr _ = GIgnore
mkLeaf :: (a -> GenLeaf) -> (a -> GenAST)
mkLeaf = (GLeaf .)
simplifyNode (GNode constr []) | (show constr) == "[]" = GNested []
simplifyNode (GNode constr [hd,GNested tl]) | (show constr) == "(:)" = GNested (hd:tl)
simplifyNode (GNode constr [a,b]) | (show constr) == "(,)" = GNested [a,b]
simplifyNode (GNode constr [a,b,c]) | (show constr) == "(,,)" = GNested [a,b,c]
simplifyNode (GNode constr []) | (show constr) == "Nothing" = GNested []
simplifyNode (GNode constr [a]) | (show constr) == "Just" = GNested [a]
simplifyNode node = node