module Ermine.Pattern.Env
( PatternEnv(..)
, dummyPatternEnv
, MonadPattern(..)
, isSignature
, constructorTag
, constructorGlobal
) where
import Prelude hiding (all)
import Control.Applicative
import Control.Lens
import Data.HashMap.Lazy (HashMap)
import qualified Data.HashMap.Lazy as HM
import Data.Set (Set)
import qualified Data.Set as S
import Data.Word
import Ermine.Builtin.Global
import Ermine.Syntax.Convention
import Ermine.Syntax.Global
import Ermine.Syntax.Pattern
#ifdef HLINT
#endif
newtype PatternEnv = PatternEnv { signatures :: HashMap Global (HashMap Global ([Convention], Word64)) }
deriving (Eq, Show)
dummyPatternEnv :: PatternEnv
dummyPatternEnv = PatternEnv $
HM.fromList [(eg, esig), (justg, maybesig), (nothingg, maybesig), (longhg, longsig)]
where
longsig = HM.singleton longhg ([U], 0)
esig = HM.singleton eg ([C], 0)
maybesig = HM.fromList [(nothingg, ([], 0)), (justg, ([C], 1))]
class (Applicative m, Monad m) => MonadPattern m where
askPattern :: m PatternEnv
instance MonadPattern ((->) PatternEnv) where
askPattern = id
isSignature :: MonadPattern m => Set PatternHead -> m Bool
isSignature ps = case preview folded ps of
Nothing -> pure False
Just (LitH _) -> pure False
Just (TupH _) -> pure True
Just (ConH _ g) -> askPattern <&> \env -> case HM.lookup g $ signatures env of
Nothing -> error "PANIC: isSignature: unknown constructor"
Just hm
| ns <- S.map (\(ConH _ g') -> g') ps -> iall (\g' _ -> S.member g' ns) hm
constructorTag :: MonadPattern m => PatternHead -> m ([Convention], Word64)
constructorTag (LitH _) = error "PANIC: constructorTag: literal head"
constructorTag (TupH n) = pure (replicate (fromIntegral n) C, 0)
constructorTag (ConH _ g) = askPattern <&> \env ->
case HM.lookup g (signatures env) >>= HM.lookup g of
Nothing -> error "PANIC: constructorTag: unknown constructor"
Just i -> i
constructorGlobal :: PatternHead -> Global
constructorGlobal (TupH n) = tupleg n
constructorGlobal (ConH _ g) = g
constructorGlobal LitH{} = error "PANIC: constructorGlobal: literal head"