hs-bindgen-1.0.0.0: src-internal/HsBindgen/Frontend/Pass/PrepareReparse/Simplifier.hs
-- | Simplifiers for 'PreHeader'
--
-- This module is intended to be imported unqualified. It is also intended to only
-- be imported from within the "HsBindgen.Frontend.Pass.PrepareReparse" module
-- hierarchy.
--
-- > import HsBindgen.Frontend.Pass.PrepareReparse.Simplifier
--
module HsBindgen.Frontend.Pass.PrepareReparse.Simplifier (
simplify
, Simplify
-- * Tags
, fieldTag
, functionTag
, typedefTag
, variableTag
) where
import Prelude hiding (print)
import Data.Either
import Data.Kind
import Clang.HighLevel.Types
import HsBindgen.Frontend.Pass.Parse.IsPass
import HsBindgen.Frontend.Pass.PrepareReparse.AST
import HsBindgen.Frontend.Pass.PrepareReparse.Flatten
import HsBindgen.Frontend.Pass.PrepareReparse.Printer.Util qualified as P
import HsBindgen.Frontend.Pass.TypecheckMacros.IsPass
import HsBindgen.Frontend.TranslationUnit qualified as C
import HsBindgen.IR.C qualified as C
import HsBindgen.Macro.Flip
{-------------------------------------------------------------------------------
Top-level
-------------------------------------------------------------------------------}
simplify :: Simplify a => Ctx a -> a TypecheckMacros -> Simple a
simplify = simplifyIt
{-------------------------------------------------------------------------------
Class
-------------------------------------------------------------------------------}
class Simplify a where
type Ctx a :: Type
type Ctx a = C.DeclInfo TypecheckMacros
type Simple a :: Type
type Simple a = [Either Undef Target]
simplifyIt :: Ctx a -> a TypecheckMacros -> Simple a
{-------------------------------------------------------------------------------
Instances
-------------------------------------------------------------------------------}
instance Simplify (C.TranslationUnit l) where
type Ctx (C.TranslationUnit l) = ()
type Simple (C.TranslationUnit l) = (Include -> PreHeader)
simplifyIt _ (unit) = \include -> PreHeader {
include = include
, undefs = undefs
, targets = targets
}
where
(undefs, targets) =
partitionEithers $ concatMap recurse unit.decls
recurse = simplifyIt ()
instance Simplify (C.Decl l) where
type Ctx (C.Decl l) = ()
simplifyIt _ decl = case decl.kind of
C.DeclStruct struct -> recurse struct
C.DeclUnion union -> recurse union
C.DeclTypedef typedef -> recurse typedef
C.DeclEnum enum -> recurse enum
C.DeclUntaggedEnumConstant c -> recurse c
C.DeclOpaque{} -> nothing
C.DeclMacro macro -> recurse $ Flip macro
C.DeclFunction function -> recurse function
C.DeclGlobal global -> recurse global
where
recurse :: forall a.
(Simplify a, Ctx a ~ C.DeclInfo TypecheckMacros)
=> a TypecheckMacros
-> Simple a
recurse = simplifyIt decl.info
instance Simplify C.Struct where
simplifyIt info struct =
concatMap (simplifyIt info) struct.fields ++
foldMap (simplifyIt info) (C.flamStructField struct.flam)
instance Simplify C.Union where
simplifyIt info union = concatMap (simplifyIt info) union.fields
instance Simplify C.Field where
simplifyIt info = C.elimField (simplifyIt info) (simplifyIt info)
instance Simplify C.RegularField where
simplifyIt info field = case field.ann of
ReparseNotNeeded -> nothing
ReparseNeeded tokens _macroInvs -> singleTarget $
Target (fieldTag info field.info) (defaultDecl tokens)
instance Simplify C.ImplicitField where
simplifyIt info field = concatMap (simplifyIt info) field.indirect
instance Simplify C.IndirectField where
simplifyIt info field = case field.ann of
ReparseNotNeeded -> nothing
ReparseNeeded tokens _macroInvs -> singleTarget $
Target (fieldTag info field.info) (defaultDecl tokens)
instance Simplify C.Typedef where
simplifyIt info typedef = case typedef.ann of
ReparseNotNeeded -> nothing
ReparseNeeded tokens _macroInvs -> singleTarget $
Target (typedefTag info) (defaultDecl tokens)
instance Simplify C.Enum where
simplifyIt _ _ = nothing
instance Simplify C.UntaggedEnumConstant where
simplifyIt _ _ = nothing
instance Simplify (Flip TypecheckedMacro l) where
simplifyIt info (Flip m) = case m of
MacroType{} -> singleUndef $ Undef (MacroName (P.name info ""))
MacroValue{} -> nothing
instance Simplify C.Function where
simplifyIt info function = case function.ann of
ReparseNotNeeded -> nothing
ReparseNeeded tokens _macroInvs -> singleTarget $
Target (functionTag info) (functionDecl tokens)
instance Simplify C.Global where
simplifyIt info global = case global.ann of
ReparseNotNeeded -> nothing
ReparseNeeded tokens _macroInvs -> singleTarget $
Target (variableTag info) (defaultDecl tokens)
{-------------------------------------------------------------------------------
Lift into Simple
-------------------------------------------------------------------------------}
nothing :: [Either Undef Target]
nothing = []
singleTarget :: Target -> [Either Undef Target]
singleTarget t = [Right t]
singleUndef :: Undef -> [Either Undef Target]
singleUndef u = [Left u]
{-------------------------------------------------------------------------------
Decls
-------------------------------------------------------------------------------}
defaultDecl :: [Token SourcePath TokenSpelling] -> Decl
defaultDecl tokens = Decl $ flattenDefault tokens
functionDecl :: [Token SourcePath TokenSpelling] -> Decl
functionDecl tokens = Decl $ flattenFunction tokens
{-------------------------------------------------------------------------------
Tags
-------------------------------------------------------------------------------}
fieldTag :: C.DeclInfo TypecheckMacros -> C.FieldInfo TypecheckMacros -> Tag
fieldTag info fieldInfo = Tag Field (TagName name)
where
name = P.name info . P.dot . P.fieldName fieldInfo $ ""
functionTag :: C.DeclInfo TypecheckMacros -> Tag
functionTag info = Tag Function (TagName (P.name info ""))
typedefTag :: C.DeclInfo TypecheckMacros -> Tag
typedefTag info = Tag Typedef (TagName (P.name info ""))
variableTag :: C.DeclInfo TypecheckMacros -> Tag
variableTag info = Tag Variable (TagName (P.name info ""))