{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
module Jikka.Core.Convert.RemoveUnusedVars
( run,
run',
)
where
import Jikka.Common.Error
import Jikka.Core.Language.Expr
import Jikka.Core.Language.FreeVars (isUnusedVar)
import Jikka.Core.Language.Lint
import Jikka.Core.Language.Util
runExpr :: [(VarName, Type)] -> Expr -> Expr
runExpr :: [(VarName, Type)] -> Expr -> Expr
runExpr [(VarName, Type)]
_ = ([(VarName, Type)] -> Expr -> Expr)
-> [(VarName, Type)] -> Expr -> Expr
mapSubExpr [(VarName, Type)] -> Expr -> Expr
forall p. p -> Expr -> Expr
go []
where
go :: p -> Expr -> Expr
go p
_ = \case
Let VarName
x Type
_ Expr
_ Expr
e2 | VarName
x VarName -> Expr -> Bool
`isUnusedVar` Expr
e2 -> Expr
e2
Expr
e -> Expr
e
runToplevelExpr :: [(VarName, Type)] -> ToplevelExpr -> ToplevelExpr
runToplevelExpr :: [(VarName, Type)] -> ToplevelExpr -> ToplevelExpr
runToplevelExpr [(VarName, Type)]
_ = \case
ToplevelLetRec VarName
f [(VarName, Type)]
args Type
ret Expr
body ToplevelExpr
cont ->
if VarName -> Expr -> Bool
isUnusedVar VarName
f Expr
body
then VarName -> Type -> Expr -> ToplevelExpr -> ToplevelExpr
ToplevelLet VarName
f ([Type] -> Type -> Type
curryFunTy (((VarName, Type) -> Type) -> [(VarName, Type)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (VarName, Type) -> Type
forall a b. (a, b) -> b
snd [(VarName, Type)]
args) Type
ret) ([(VarName, Type)] -> Expr -> Expr
curryLam [(VarName, Type)]
args Expr
body) ToplevelExpr
cont
else VarName
-> [(VarName, Type)]
-> Type
-> Expr
-> ToplevelExpr
-> ToplevelExpr
ToplevelLetRec VarName
f [(VarName, Type)]
args Type
ret Expr
body ToplevelExpr
cont
ToplevelExpr
e -> ToplevelExpr
e
run' :: Program -> Program
run' :: ToplevelExpr -> ToplevelExpr
run' = ([(VarName, Type)] -> ToplevelExpr -> ToplevelExpr)
-> ToplevelExpr -> ToplevelExpr
mapToplevelExprProgram [(VarName, Type)] -> ToplevelExpr -> ToplevelExpr
runToplevelExpr (ToplevelExpr -> ToplevelExpr)
-> (ToplevelExpr -> ToplevelExpr) -> ToplevelExpr -> ToplevelExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(VarName, Type)] -> Expr -> Expr) -> ToplevelExpr -> ToplevelExpr
mapExprProgram (([(VarName, Type)] -> Expr -> Expr)
-> [(VarName, Type)] -> Expr -> Expr
mapSubExpr [(VarName, Type)] -> Expr -> Expr
runExpr)
run :: MonadError Error m => Program -> m Program
run :: ToplevelExpr -> m ToplevelExpr
run ToplevelExpr
prog = String -> m ToplevelExpr -> m ToplevelExpr
forall (m :: * -> *) a. MonadError Error m => String -> m a -> m a
wrapError' String
"Jikka.Core.Convert.RemoveUnusedVars" (m ToplevelExpr -> m ToplevelExpr)
-> m ToplevelExpr -> m ToplevelExpr
forall a b. (a -> b) -> a -> b
$ do
m () -> m ()
forall (m :: * -> *) a. MonadError Error m => m a -> m a
precondition (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
ToplevelExpr -> m ()
forall (m :: * -> *). MonadError Error m => ToplevelExpr -> m ()
lint ToplevelExpr
prog
ToplevelExpr
prog <- ToplevelExpr -> m ToplevelExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (ToplevelExpr -> m ToplevelExpr) -> ToplevelExpr -> m ToplevelExpr
forall a b. (a -> b) -> a -> b
$ ToplevelExpr -> ToplevelExpr
run' ToplevelExpr
prog
m () -> m ()
forall (m :: * -> *) a. MonadError Error m => m a -> m a
postcondition (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
ToplevelExpr -> m ()
forall (m :: * -> *). MonadError Error m => ToplevelExpr -> m ()
lint ToplevelExpr
prog
ToplevelExpr -> m ToplevelExpr
forall (m :: * -> *) a. Monad m => a -> m a
return ToplevelExpr
prog