module Agda.Compiler.Treeless.EliminateDefaults where
import Control.Monad
import qualified Data.List as List
import Agda.Syntax.Treeless
import Agda.TypeChecking.Monad
import Agda.TypeChecking.Substitute
import Agda.Compiler.Treeless.Subst ()
eliminateCaseDefaults :: TTerm -> TCM TTerm
eliminateCaseDefaults :: TTerm -> TCM TTerm
eliminateCaseDefaults = TTerm -> TCM TTerm
tr
where
tr :: TTerm -> TCM TTerm
tr :: TTerm -> TCM TTerm
tr = \case
TCase Int
sc ct :: CaseInfo
ct@CaseInfo{caseType :: CaseInfo -> CaseType
caseType = CTData Quantity
_ QName
qn} TTerm
def [TAlt]
alts
| Bool -> Bool
not (forall a. Unreachable a => a -> Bool
isUnreachable TTerm
def) -> do
[QName]
dtCons <- Defn -> [QName]
defConstructors forall b c a. (b -> c) -> (a -> b) -> a -> c
. Definition -> Defn
theDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). HasConstInfo m => QName -> m Definition
getConstInfo QName
qn
let missingCons :: [QName]
missingCons = [QName]
dtCons forall a. Eq a => [a] -> [a] -> [a]
List.\\ forall a b. (a -> b) -> [a] -> [b]
map TAlt -> QName
aCon [TAlt]
alts
TTerm
def <- TTerm -> TCM TTerm
tr TTerm
def
[TAlt]
newAlts <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [QName]
missingCons forall a b. (a -> b) -> a -> b
$ \QName
con -> do
Constructor {conArity :: Defn -> Int
conArity = Int
ar} <- Definition -> Defn
theDef forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *). HasConstInfo m => QName -> m Definition
getConstInfo QName
con
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ QName -> Int -> TTerm -> TAlt
TACon QName
con Int
ar (Int -> TTerm
TVar Int
ar)
[TAlt]
alts' <- (forall a. [a] -> [a] -> [a]
++ [TAlt]
newAlts) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (TAlt -> TCMT IO TAlt
trAlt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Subst a => Int -> a -> a
raise Int
1) [TAlt]
alts
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ TTerm -> TTerm -> TTerm
TLet TTerm
def forall a b. (a -> b) -> a -> b
$ Int -> CaseInfo -> TTerm -> [TAlt] -> TTerm
TCase (Int
sc forall a. Num a => a -> a -> a
+ Int
1) CaseInfo
ct TTerm
tUnreachable [TAlt]
alts'
TCase Int
sc CaseInfo
ct TTerm
def [TAlt]
alts -> Int -> CaseInfo -> TTerm -> [TAlt] -> TTerm
TCase Int
sc CaseInfo
ct forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
def forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TAlt -> TCMT IO TAlt
trAlt [TAlt]
alts
t :: TTerm
t@TVar{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TDef{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TCon{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TPrim{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TLit{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TUnit{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TSort{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TErased{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
t :: TTerm
t@TError{} -> forall (m :: * -> *) a. Monad m => a -> m a
return TTerm
t
TCoerce TTerm
a -> TTerm -> TTerm
TCoerce forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
a
TLam TTerm
b -> TTerm -> TTerm
TLam forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
b
TApp TTerm
a Args
bs -> TTerm -> Args -> TTerm
TApp forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
a forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM TTerm -> TCM TTerm
tr Args
bs
TLet TTerm
e TTerm
b -> TTerm -> TTerm -> TTerm
TLet forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
e forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TTerm -> TCM TTerm
tr TTerm
b
trAlt :: TAlt -> TCM TAlt
trAlt :: TAlt -> TCMT IO TAlt
trAlt = \case
TAGuard TTerm
g TTerm
b -> TTerm -> TTerm -> TAlt
TAGuard forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
g forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TTerm -> TCM TTerm
tr TTerm
b
TACon QName
q Int
a TTerm
b -> QName -> Int -> TTerm -> TAlt
TACon QName
q Int
a forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
b
TALit Literal
l TTerm
b -> Literal -> TTerm -> TAlt
TALit Literal
l forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TTerm -> TCM TTerm
tr TTerm
b