module DDC.Core.Check.CheckDaCon
(checkDaConM)
where
import DDC.Core.Check.Error
import DDC.Core.Check.CheckWitness
import DDC.Core.Exp.DaCon
import DDC.Core.Exp
import DDC.Type.Compounds
import DDC.Type.DataDef
import DDC.Control.Monad.Check (throw)
import Control.Monad
import Prelude as L
import qualified Data.Map as Map
checkDaConM
:: (Ord n, Eq n, Show n)
=> Config n
-> Exp a n
-> DaCon n
-> CheckM a n ()
checkDaConM _ _ dc
| DaConUnit <- daConName dc
= return ()
checkDaConM config xx dc
| DaConNamed nCtor <- daConName dc
, daConIsAlgebraic dc
= let tResult = snd $ takeTFunArgResult $ eraseTForalls $ typeOfDaCon dc
defs = configPrimDataDefs config
in case liftM fst $ takeTyConApps tResult of
Just (TyConBound u _)
| Just nType <- takeNameOfBound u
, Just dataType <- Map.lookup nType (dataDefsTypes defs)
-> case dataTypeMode dataType of
DataModeSmall nsCtors
| L.elem nCtor nsCtors -> return ()
| otherwise -> throw $ ErrorUndefinedCtor xx
DataModeLarge -> return ()
_ -> throw $ ErrorUndefinedCtor xx
checkDaConM _ _ _
= return ()