{-# LANGUAGE OverloadedStrings #-}
module Language.Del.Inlining (substFuncs, uniqueParams) where
import qualified Data.Map.Strict as Map
import qualified Data.Text as T
import Language.Del.AST
import Language.Del.AstUtils
import Language.Del.CompileDefs
-- Replace function parameters with unique names
uniqueParams' :: Def -> Def
uniqueParams' (Def name ret params body) =
let newParams = map (\(p, t) -> (T.concat [name, "/", p], t)) params in
Def name ret newParams
(mapexpr (swapNames (Map.fromList $ zip (map fst params) (map fst newParams))) body)
uniqueParams :: AST -> Artifact AST
uniqueParams = return . mapast uniqueParams'
-- Replace function calls with let-bindings
substFunc :: AST -> Expr -> Expr
substFunc (AST m _) e@(Apply (Id name) aargs) =
case Map.lookup name m of
Just (Def _ _ dargs body) -> makeLets (zip (map fst dargs) aargs) body
Nothing -> e
substFunc _ e = e
makeLets :: [(Name, Expr)] -> Expr -> Expr
makeLets ((n, a):xs) e = Let n a $ makeLets xs e
makeLets [] e = e
substFuncs :: AST -> Artifact AST
substFuncs ast@(AST m imps) = return $ AST newbinds imps
where sub (Def n ret a b) = Def n ret a $ mapexpr (substFunc ast) b
newbinds = Map.adjust sub rootKey m