alms-0.4.9: src/Syntax/Patt.hs
{-# LANGUAGE
DeriveDataTypeable,
FlexibleInstances,
MultiParamTypeClasses,
NoMonomorphismRestriction,
TemplateHaskell,
TypeFamilies,
TypeSynonymInstances #-}
module Syntax.Patt (
Patt'(..), Patt, PattNote(..), newPatt,
paWild, paVar, paCon, paPair, paLit, paAs, paPack, paAnti,
dtv
) where
import Meta.DeriveNotable
import Syntax.Notable
import Syntax.Anti
import Syntax.Ident
import Syntax.Lit
import qualified Data.Set as S
import Data.Generics (Typeable, Data)
type Patt i = N (PattNote i) (Patt' i)
-- | Patterns
data Patt' i
-- | wildcard
= PaWild
-- | variable pattern
| PaVar (Lid i)
-- | datacon, possibly with parameter, possibly an exception
| PaCon (QUid i) (Maybe (Patt i))
-- | pair pattern
| PaPair (Patt i) (Patt i)
-- | literal pattern
| PaLit Lit
-- | bind an identifer and a pattern (@as@)
| PaAs (Patt i) (Lid i)
-- | existential opening
| PaPack (TyVar i) (Patt i)
-- | antiquote
| PaAnti Anti
deriving (Typeable, Data)
data PattNote i
= PattNote {
-- | source location
ploc_ :: !Loc,
-- | defined variables
pdv_ :: S.Set (Lid i),
-- | defined type variables
pdtv_ :: S.Set (TyVar i)
}
deriving (Typeable, Data)
instance Locatable (PattNote i) where
getLoc = ploc_
instance Relocatable (PattNote i) where
setLoc note loc = note { ploc_ = loc }
instance Notable (PattNote i) where
newNote = PattNote bogus S.empty S.empty
newPatt :: Id i => Patt' i -> Patt i
newPatt p0 = flip N p0 $ case p0 of
PaWild ->
newNote {
pdv_ = S.empty,
pdtv_ = S.empty
}
PaVar x ->
newNote {
pdv_ = S.singleton x,
pdtv_ = S.empty
}
PaCon _ Nothing ->
newNote {
pdv_ = S.empty,
pdtv_ = S.empty
}
PaCon _ (Just x) ->
newNote {
pdv_ = dv x,
pdtv_ = dtv x
}
PaPair x y ->
newNote {
pdv_ = dv x `S.union` dv y,
pdtv_ = dtv x `S.union` dtv y
}
PaLit _ ->
newNote {
pdv_ = S.empty,
pdtv_ = S.empty
}
PaAs x y ->
newNote {
pdv_ = S.insert y (dv x),
pdtv_ = dtv x
}
PaPack tv x ->
newNote {
pdv_ = dv x,
pdtv_ = S.insert tv (dtv x)
}
PaAnti a ->
newNote {
pdv_ = antierror "dv" a,
pdtv_ = antierror "dtv" a
}
instance Id i => Dv (N (PattNote i) a) i where
dv = pdv_ . noteOf
dtv :: Id i => Patt i -> S.Set (TyVar i)
dtv = pdtv_ . noteOf
deriveNotable 'newPatt (''Id, [0]) ''Patt