module DDC.Core.Transform.Inline.Templates
( InlineSpec(..)
, lookupTemplateFromModules
, lookupTemplateFromModule )
where
import DDC.Core.Exp
import DDC.Core.Module
import DDC.Core.Transform.AnonymizeX
import Data.List
import Data.Set (Set)
import Data.Map (Map)
import qualified Data.Map as Map
import qualified Data.Set as Set
data InlineSpec n
= InlineSpecAll
{ inlineSpecModuleName :: ModuleName
, inlineSpecExclude :: Set n }
| InlineSpecNone
{ inlineSpecModuleName :: ModuleName
, inlineSpecInclude :: Set n }
deriving Show
lookupTemplateFromModules
:: (Eq n, Ord n, Show n)
=> Map ModuleName (InlineSpec n)
-> [Module a n]
-> n
-> Maybe (Exp a n)
lookupTemplateFromModules specs mm n
| m : ms <- mm
= let
spec = case Map.lookup (moduleName m) specs of
Just s -> s
Nothing -> InlineSpecNone (moduleName m) Set.empty
in case lookupTemplateFromModule spec m n of
Nothing -> lookupTemplateFromModules specs ms n
Just x -> Just x
| otherwise
= Nothing
lookupTemplateFromModule
:: (Eq n, Ord n, Show n)
=> InlineSpec n
-> Module a n
-> n
-> Maybe (Exp a n)
lookupTemplateFromModule spec mm n
| shouldInline spec n
, XLet _ (LRec bxs) _ <- moduleBody mm
, Just (_,x) <- find (\(BName n' _, _) -> n == n') bxs
= Just $ anonymizeX x
| otherwise
= Nothing
shouldInline
:: (Ord n, Show n)
=> InlineSpec n -> n -> Bool
shouldInline spec n
= case spec of
InlineSpecAll _ except
| Set.member n except -> False
| otherwise -> True
InlineSpecNone _ include
| Set.member n include -> True
| otherwise -> False