module DDC.Core.Transform.Inline
( inline
, InlineSpec (..)
, lookupTemplateFromModules)
where
import DDC.Core.Exp
import DDC.Core.Module
import DDC.Core.Transform.Inline.Templates
import qualified Data.Set as Set
import Data.Set (Set)
class Inline (c :: * -> * -> *) where
inline :: Ord n
=> (n -> Maybe (Exp a n))
-> Set n
-> c a n
-> c a n
instance Inline Module where
inline get inside mm
= mm { moduleBody = inline get inside (moduleBody mm) }
instance Inline Exp where
inline get inside xx
= let down x = inline get inside x
in case xx of
XVar _ (UName n)
| Set.member n inside
-> xx
| Just xx' <- get n
-> let !inside' = Set.insert n inside
in inline get inside' xx'
XVar{} -> xx
XCon{} -> xx
XLAM a b x -> XLAM a b (down x)
XLam a b x -> XLam a b (down x)
XApp a x1 x2 -> XApp a (down x1) (down x2)
XLet a lts x2 -> XLet a (down lts) (down x2)
XCase a x alts -> XCase a (down x) (map down alts)
XCast a c x -> XCast a c (down x)
XType{} -> xx
XWitness{} -> xx
instance Inline Lets where
inline get inside lts
= let enter b x
= case b of
BName n _ -> inline get (Set.insert n inside) x
_ -> inline get inside x
in case lts of
LLet b x -> LLet b (enter b x)
LRec bxs -> LRec [(b, enter b x) | (b, x) <- bxs]
LPrivate{} -> lts
LWithRegion{} -> lts
instance Inline Alt where
inline get inside alt
= case alt of
AAlt p x -> AAlt p (inline get inside x)