cimple-0.0.21: src/Language/Cimple/TraverseAst.hs
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE TypeFamilies #-}
module Language.Cimple.TraverseAst
( traverseAst
, doFiles, doFile
, doNodes, doNode
, doComment, doComments
, doLexemes, doLexeme
, doText
, astActions, AstActions
) where
import Data.Fix (Fix (..))
import Data.Foldable (traverse_)
import Language.Cimple.Ast (Comment, CommentF (..), Node,
NodeF (..))
import Language.Cimple.Lexer (Lexeme (..))
{-# ANN module "HLint: ignore Reduce duplication" #-}
class TraverseAst text a where
traverseFileAst
:: Applicative f
=> AstActions f text
-> FilePath
-> a
-> f ()
traverseAst
:: (TraverseAst text a, Applicative f)
=> AstActions f text -> a
-> f ()
traverseAst = flip traverseFileAst "<stdin>"
data AstActions f text = AstActions
{ doFiles :: [(FilePath, [Node (Lexeme text)])] -> f () -> f ()
, doFile :: (FilePath, [Node (Lexeme text)]) -> f () -> f ()
, doNodes :: FilePath -> [Node (Lexeme text)] -> f () -> f ()
, doNode :: FilePath -> Node (Lexeme text) -> f () -> f ()
, doComment :: FilePath -> Comment (Lexeme text) -> f () -> f ()
, doComments :: FilePath -> [Comment (Lexeme text)] -> f () -> f ()
, doLexemes :: FilePath -> [Lexeme text] -> f () -> f ()
, doLexeme :: FilePath -> Lexeme text -> f () -> f ()
, doText :: FilePath -> text -> f ()
}
instance TraverseAst text a
=> TraverseAst text (Maybe a) where
traverseFileAst _ _ Nothing = pure ()
traverseFileAst actions currentFile (Just x) =
traverseFileAst actions currentFile x
astActions
:: Applicative f
=> AstActions f text
astActions = AstActions
{ doFiles = const id
, doFile = const id
, doNodes = const $ const id
, doNode = const $ const id
, doComment = const $ const id
, doComments = const $ const id
, doLexeme = const $ const id
, doLexemes = const $ const id
, doText = const $ const $ pure ()
}
instance TraverseAst text (Lexeme text) where
traverseFileAst :: forall f . Applicative f
=> AstActions f text -> FilePath -> Lexeme text -> f ()
traverseFileAst AstActions{..} currentFile = doLexeme currentFile <*>
\(L _ _ s) -> doText currentFile s
instance TraverseAst text [Lexeme text] where
traverseFileAst actions@AstActions{..} currentFile = doLexemes currentFile <*>
traverse_ (traverseFileAst actions currentFile)
instance TraverseAst text (Comment (Lexeme text)) where
traverseFileAst
:: forall f . Applicative f
=> AstActions f text
-> FilePath
-> Comment (Lexeme text)
-> f ()
traverseFileAst actions@AstActions{..} currentFile = doComment currentFile <*> \comment -> case unFix comment of
DocComment docs ->
recurse docs
DocWord word ->
recurse word
DocSentence docs ending -> do
_ <- recurse docs
_ <- recurse ending
pure ()
DocNewline -> pure ()
DocAttention docs ->
recurse docs
DocBrief docs ->
recurse docs
DocDeprecated docs ->
recurse docs
DocExtends feat ->
recurse feat
DocImplements feat ->
recurse feat
DocParam attr name docs -> do
_ <- recurse attr
_ <- recurse name
_ <- recurse docs
pure ()
DocReturn docs ->
recurse docs
DocRetval expr docs -> do
_ <- recurse expr
_ <- recurse docs
pure ()
DocSee ref docs -> do
_ <- recurse ref
_ <- recurse docs
pure ()
DocPrivate -> pure ()
DocParagraph docs ->
recurse docs
DocLine docs ->
recurse docs
DocCode begin docs end -> do
_ <- recurse begin
_ <- recurse docs
_ <- recurse end
pure ()
DocList docs ->
recurse docs
DocOLItem docs sublist -> do
_ <- recurse docs
_ <- recurse sublist
pure ()
DocULItem docs sublist -> do
_ <- recurse docs
_ <- recurse sublist
pure ()
DocColon docs ->
recurse docs
DocRef doc ->
recurse doc
DocP doc ->
recurse doc
DocLParen docs ->
recurse docs
DocRParen docs ->
recurse docs
DocAssignOp _ lhs rhs -> do
_ <- recurse lhs
_ <- recurse rhs
pure ()
DocBinaryOp _ lhs rhs -> do
_ <- recurse lhs
_ <- recurse rhs
pure ()
where
recurse :: TraverseAst text a => a -> f ()
recurse = traverseFileAst actions currentFile
instance TraverseAst text [Comment (Lexeme text)] where
traverseFileAst actions@AstActions{..} currentFile = doComments currentFile <*>
traverse_ (traverseFileAst actions currentFile)
instance TraverseAst text (Node (Lexeme text)) where
traverseFileAst
:: forall f . Applicative f
=> AstActions f text
-> FilePath
-> Node (Lexeme text)
-> f ()
traverseFileAst actions@AstActions{..} currentFile = doNode currentFile <*> \node -> case unFix node of
PreprocInclude path ->
recurse path
PreprocDefine name ->
recurse name
PreprocDefineConst name value -> do
_ <- recurse name
_ <- recurse value
pure ()
PreprocDefineMacro name params body -> do
_ <- recurse name
_ <- recurse params
_ <- recurse body
pure ()
PreprocIf cond thenDecls elseBranch -> do
_ <- recurse cond
_ <- recurse thenDecls
_ <- recurse elseBranch
pure ()
PreprocIfdef name thenDecls elseBranch -> do
_ <- recurse name
_ <- recurse thenDecls
_ <- recurse elseBranch
pure ()
PreprocIfndef name thenDecls elseBranch -> do
_ <- recurse name
_ <- recurse thenDecls
_ <- recurse elseBranch
pure ()
PreprocElse decls ->
recurse decls
PreprocElif cond decls elseBranch -> do
_ <- recurse cond
_ <- recurse decls
_ <- recurse elseBranch
pure ()
PreprocUndef name ->
recurse name
PreprocDefined name ->
recurse name
PreprocScopedDefine define stmts undef -> do
_ <- recurse define
_ <- recurse stmts
_ <- recurse undef
pure ()
MacroBodyStmt stmts ->
recurse stmts
MacroBodyFunCall expr ->
recurse expr
MacroParam name ->
recurse name
StaticAssert cond msg -> do
_ <- recurse cond
_ <- recurse msg
pure ()
LicenseDecl license copyrights -> do
_ <- recurse license
_ <- recurse copyrights
pure ()
CopyrightDecl from to owner -> do
_ <- recurse from
_ <- recurse to
_ <- recurse owner
pure ()
Comment _doc start contents end -> do
_ <- recurse start
_ <- recurse contents
_ <- recurse end
pure ()
CommentSection start decls end -> do
_ <- recurse start
_ <- recurse decls
_ <- recurse end
pure ()
CommentSectionEnd comment -> do
_ <- recurse comment
pure ()
Commented comment subject -> do
_ <- recurse comment
_ <- recurse subject
pure ()
CommentInfo comment ->
recurse comment
ExternC decls ->
recurse decls
Group decls ->
recurse decls
CompoundStmt stmts ->
recurse stmts
Break ->
pure ()
Goto label ->
recurse label
Continue ->
pure ()
Return value ->
recurse value
SwitchStmt value cases -> do
_ <- recurse value
_ <- recurse cases
pure ()
IfStmt cond thenStmts elseStmt -> do
_ <- recurse cond
_ <- recurse thenStmts
_ <- recurse elseStmt
pure ()
ForStmt initStmt cond next stmts -> do
_ <- recurse initStmt
_ <- recurse cond
_ <- recurse next
_ <- recurse stmts
pure ()
WhileStmt cond stmts -> do
_ <- recurse cond
_ <- recurse stmts
pure ()
DoWhileStmt stmts cond -> do
_ <- recurse stmts
_ <- recurse cond
pure ()
Case value stmt -> do
_ <- recurse value
_ <- recurse stmt
pure ()
Default stmt ->
recurse stmt
Label label stmt -> do
_ <- recurse label
_ <- recurse stmt
pure ()
ExprStmt expr -> do
_ <- recurse expr
pure ()
VLA ty name size -> do
_ <- recurse ty
_ <- recurse name
_ <- recurse size
pure ()
VarDeclStmt decl ini -> do
_ <- recurse decl
_ <- recurse ini
pure ()
VarDecl ty name arrs -> do
_ <- recurse ty
_ <- recurse name
_ <- recurse arrs
pure ()
DeclSpecArray size ->
recurse size
InitialiserList values ->
recurse values
UnaryExpr _op expr ->
recurse expr
BinaryExpr lhs _op rhs -> do
_ <- recurse lhs
_ <- recurse rhs
pure ()
TernaryExpr cond thenExpr elseExpr -> do
_ <- recurse cond
_ <- recurse thenExpr
_ <- recurse elseExpr
pure ()
AssignExpr lhs _op rhs -> do
_ <- recurse lhs
_ <- recurse rhs
pure ()
ParenExpr expr ->
recurse expr
CastExpr ty expr -> do
_ <- recurse ty
_ <- recurse expr
pure ()
CompoundExpr ty expr -> do -- DEPRECATED
_ <- recurse ty
_ <- recurse expr
pure ()
CompoundLiteral ty expr -> do
_ <- recurse ty
_ <- recurse expr
pure ()
SizeofExpr expr ->
recurse expr
SizeofType ty ->
recurse ty
LiteralExpr _ty value ->
recurse value
VarExpr name ->
recurse name
MemberAccess name field -> do
_ <- recurse name
_ <- recurse field
pure ()
PointerAccess name field -> do
_ <- recurse name
_ <- recurse field
pure ()
ArrayAccess arr idx -> do
_ <- recurse arr
_ <- recurse idx
pure ()
FunctionCall callee args -> do
_ <- recurse callee
_ <- recurse args
pure ()
CommentExpr comment expr -> do
_ <- recurse comment
_ <- recurse expr
pure ()
EnumConsts name members -> do
_ <- recurse name
_ <- recurse members
pure ()
EnumDecl name members tyName -> do
_ <- recurse name
_ <- recurse members
_ <- recurse tyName
pure ()
Enumerator name value -> do
_ <- recurse name
_ <- recurse value
pure ()
AggregateDecl struct -> do
_ <- recurse struct
pure ()
Typedef ty name -> do
_ <- recurse ty
_ <- recurse name
pure ()
TypedefFunction ty ->
recurse ty
Struct name members -> do
_ <- recurse name
_ <- recurse members
pure ()
Union name members -> do
_ <- recurse name
_ <- recurse members
pure ()
MemberDecl decl bits -> do
_ <- recurse decl
_ <- recurse bits
pure ()
TyBitwise ty ->
recurse ty
TyForce ty ->
recurse ty
TyConst ty ->
recurse ty
TyOwner ty ->
recurse ty
TyPointer ty ->
recurse ty
TyStruct name ->
recurse name
TyFunc name ->
recurse name
TyStd name ->
recurse name
TyUserDefined name ->
recurse name
AttrPrintf fmt ellipsis fun -> do
_ <- recurse fmt
_ <- recurse ellipsis
_ <- recurse fun
pure ()
FunctionDecl _scope proto ->
recurse proto
FunctionDefn _scope proto body -> do
_ <- recurse proto
_ <- recurse body
pure ()
FunctionPrototype ty name params -> do
_ <- recurse ty
_ <- recurse name
_ <- recurse params
pure ()
CallbackDecl ty name -> do
_ <- recurse ty
_ <- recurse name
pure ()
Ellipsis ->
pure ()
NonNull nonnull nullable f -> do
_ <- recurse nonnull
_ <- recurse nullable
_ <- recurse f
pure ()
ConstDecl ty name -> do
_ <- recurse ty
_ <- recurse name
pure ()
ConstDefn _scope ty name value -> do
_ <- recurse ty
_ <- recurse name
_ <- recurse value
pure ()
where
recurse :: TraverseAst text a => a -> f ()
recurse = traverseFileAst actions currentFile
instance TraverseAst text [Node (Lexeme text)] where
traverseFileAst actions@AstActions{..} currentFile = doNodes currentFile <*>
traverse_ (traverseFileAst actions currentFile)
instance TraverseAst text (FilePath, [Node (Lexeme text)]) where
traverseFileAst actions@AstActions{..} _ tu@(currentFile, _) = doFile <*>
traverse_ (traverseFileAst actions currentFile) $ tu
instance TraverseAst text [(FilePath, [Node (Lexeme text)])] where
traverseFileAst actions@AstActions{..} currentFile = doFiles <*>
traverse_ (traverseFileAst actions currentFile)