module Language.Clafer.Intermediate.Intclafer where
import Language.Clafer.Front.Absclafer
import Control.Lens
import Data.Data
import Data.Monoid
import Data.Foldable (foldMap)
type UID = String
type CName = String
data Ir =
IRIModule IModule |
IRIElement IElement |
IRIType IType |
IRClafer IClafer |
IRIExp IExp |
IRPExp PExp |
IRISuper ISuper |
IRIQuant IQuant |
IRIDecl IDecl |
IRIGCard IGCard
deriving (Eq, Show)
data IType = TBoolean
| TString
| TInteger
| TReal
| TClafer [String]
deriving (Eq,Ord,Show,Data,Typeable)
data IModule = IModule {
_mName :: String,
_mDecls :: [IElement]
}
deriving (Eq,Ord,Show,Data,Typeable)
data IClafer =
IClafer {
_cinPos :: Span,
_isAbstract :: Bool,
_gcard :: Maybe IGCard,
_ident :: CName,
_uid :: UID,
_super:: ISuper,
_card :: Maybe Interval,
_glCard :: Interval,
_elements :: [IElement]
}
deriving (Eq,Ord,Show,Data,Typeable)
data IElement =
IEClafer {
_iClafer :: IClafer
}
| IEConstraint {
_isHard :: Bool,
_cpexp :: PExp
}
| IEGoal {
_isMaximize :: Bool,
_cpexp :: PExp
}
deriving (Eq,Ord,Show,Data,Typeable)
data ISuper =
ISuper {
_isOverlapping :: Bool,
_supers :: [PExp]
}
deriving (Eq,Ord,Show,Data,Typeable)
data IGCard =
IGCard {
_isKeyword :: Bool,
_interval :: Interval
}
deriving (Eq,Ord,Show,Data,Typeable)
type Interval = (Integer, Integer)
data PExp = PExp {
_iType :: Maybe IType,
_pid :: String,
_inPos :: Span,
_exp :: IExp
}
deriving (Eq,Ord,Show,Data,Typeable)
data IExp =
IDeclPExp {
_quant :: IQuant,
_oDecls :: [IDecl],
_bpexp :: PExp
}
| IFunExp {
_op :: String,
_exps :: [PExp]
}
| IInt {
_iint :: Integer
}
| IDouble {
_idouble :: Double
}
| IStr {
_istr :: String
}
| IClaferId {
_modName :: String,
_sident :: CName,
_isTop :: Bool
}
deriving (Eq,Ord,Show,Data,Typeable)
data IDecl =
IDecl {
_isDisj :: Bool,
_decls :: [CName],
_body :: PExp
}
deriving (Eq,Ord,Show,Data,Typeable)
data IQuant =
INo
| ILone
| IOne
| ISome
| IAll
deriving (Eq,Ord,Show,Data,Typeable)
type LineNo = Integer
type ColNo = Integer
mapIR :: (Ir -> Ir) -> IModule -> IModule
mapIR f (IModule name decls') =
unWrapIModule $ f $ IRIModule $ IModule name $ map (unWrapIElement . iMap f . IRIElement) decls'
foldMapIR :: (Monoid m) => (Ir -> m) -> IModule -> m
foldMapIR f i@(IModule _ decls') =
(f $ IRIModule i) `mappend` foldMap (iFoldMap f . IRIElement) decls'
foldIR :: (Ir -> a -> a) -> a -> IModule -> a
foldIR f e m = appEndo (foldMapIR (Endo . f) m) e
iMap :: (Ir -> Ir) -> Ir -> Ir
iMap f (IRIElement (IEClafer c)) =
f $ IRIElement $ IEClafer $ unWrapIClafer $ iMap f $ IRClafer c
iMap f (IRIElement (IEConstraint h pexp)) =
f $ IRIElement $ IEConstraint h $ unWrapPExp $ iMap f $ IRPExp pexp
iMap f (IRIElement (IEGoal m pexp)) =
f $ IRIElement $ IEGoal m $ unWrapPExp $ iMap f $ IRPExp pexp
iMap f (IRClafer (IClafer p a (Just grc) i u s c goc elems)) =
f $ IRClafer $ IClafer p a (Just $ unWrapIGCard $ iMap f $ IRIGCard grc) i u (unWrapISuper $ iMap f $ IRISuper s) c goc $ map (unWrapIElement . iMap f . IRIElement) elems
iMap f (IRClafer (IClafer p a Nothing i u s c goc elems)) =
f $ IRClafer $ IClafer p a Nothing i u (unWrapISuper $ iMap f $ IRISuper s) c goc $ map (unWrapIElement . iMap f . IRIElement) elems
iMap f (IRIExp (IDeclPExp q decs p)) =
f $ IRIExp $ IDeclPExp (unWrapIQuant $ iMap f $ IRIQuant q) (map (unWrapIDecl . iMap f . IRIDecl) decs) $ unWrapPExp $ iMap f $ IRPExp p
iMap f (IRIExp (IFunExp o pexps)) =
f $ IRIExp $ IFunExp o $ map (unWrapPExp . iMap f . IRPExp) pexps
iMap f (IRPExp (PExp (Just iType') pID p iExp)) =
f $ IRPExp $ PExp (Just $ unWrapIType $ iMap f $ IRIType iType') pID p $ unWrapIExp $ iMap f $ IRIExp iExp
iMap f (IRPExp (PExp Nothing pID p iExp)) =
f $ IRPExp $ PExp Nothing pID p $ unWrapIExp $ iMap f $ IRIExp iExp
iMap f (IRISuper (ISuper o pexps)) =
f $ IRISuper $ ISuper o $ map (unWrapPExp . iMap f . IRPExp) pexps
iMap f (IRIDecl (IDecl i d body')) =
f $ IRIDecl $ IDecl i d $ unWrapPExp $ iMap f $ IRPExp body'
iMap f i = f i
iFoldMap :: (Monoid m) => (Ir -> m) -> Ir -> m
iFoldMap f i@(IRIElement (IEConstraint _ pexp)) =
f i `mappend` (iFoldMap f $ IRPExp pexp)
iFoldMap f i@(IRIElement (IEGoal _ pexp)) =
f i `mappend` (iFoldMap f $ IRPExp pexp)
iFoldMap f i@(IRClafer (IClafer _ _ Nothing _ _ s _ _ elems)) =
f i `mappend` (iFoldMap f $ IRISuper s) `mappend` foldMap (iFoldMap f . IRIElement) elems
iFoldMap f i@(IRClafer (IClafer _ _ (Just grc) _ _ s _ _ elems)) =
f i `mappend` (iFoldMap f $ IRISuper s) `mappend` (iFoldMap f $ IRIGCard grc) `mappend` foldMap (iFoldMap f . IRIElement) elems
iFoldMap f i@(IRIExp (IDeclPExp q decs p)) =
f i `mappend` (iFoldMap f $ IRIQuant q) `mappend` (iFoldMap f $ IRPExp p) `mappend` foldMap (iFoldMap f . IRIDecl) decs
iFoldMap f i@(IRIExp (IFunExp _ pexps)) =
f i `mappend` foldMap (iFoldMap f . IRPExp) pexps
iFoldMap f i@(IRPExp (PExp (Just iType') _ _ iExp)) =
f i `mappend` (iFoldMap f $ IRIType iType') `mappend` (iFoldMap f $ IRIExp iExp)
iFoldMap f i@(IRPExp (PExp Nothing _ _ iExp)) =
f i `mappend` (iFoldMap f $ IRIExp iExp)
iFoldMap f i@(IRISuper (ISuper _ pexps)) =
f i `mappend` foldMap (iFoldMap f . IRPExp) pexps
iFoldMap f i@(IRIDecl (IDecl _ _ body')) =
f i `mappend` (iFoldMap f $ IRPExp body')
iFoldMap f (IRIElement (IEClafer c)) = iFoldMap f $ IRClafer c
iFoldMap f i = f i
iFold :: (Ir -> a -> a) -> a -> Ir -> a
iFold f e m = appEndo (iFoldMap (Endo . f) m) e
unWrapIModule :: Ir -> IModule
unWrapIModule (IRIModule x) = x
unWrapIModule x = error $ "Can't call unWarpIModule on " ++ show x
unWrapIElement :: Ir -> IElement
unWrapIElement (IRIElement x) = x
unWrapIElement x = error $ "Can't call unWarpIElement on " ++ show x
unWrapIType :: Ir -> IType
unWrapIType (IRIType x) = x
unWrapIType x = error $ "Can't call unWarpIType on " ++ show x
unWrapIClafer :: Ir -> IClafer
unWrapIClafer (IRClafer x) = x
unWrapIClafer x = error $ "Can't call unWarpIClafer on " ++ show x
unWrapIExp :: Ir -> IExp
unWrapIExp (IRIExp x) = x
unWrapIExp x = error $ "Can't call unWarpIExp on " ++ show x
unWrapPExp :: Ir -> PExp
unWrapPExp (IRPExp x) = x
unWrapPExp x = error $ "Can't call unWarpPExp on " ++ show x
unWrapISuper :: Ir -> ISuper
unWrapISuper (IRISuper x) = x
unWrapISuper x = error $ "Can't call unWarpISuper on " ++ show x
unWrapIQuant :: Ir -> IQuant
unWrapIQuant (IRIQuant x) = x
unWrapIQuant x = error $ "Can't call unWarpIQuant on " ++ show x
unWrapIDecl :: Ir -> IDecl
unWrapIDecl (IRIDecl x) = x
unWrapIDecl x = error $ "Can't call unWarpIDecl on " ++ show x
unWrapIGCard :: Ir -> IGCard
unWrapIGCard (IRIGCard x) = x
unWrapIGCard x = error $ "Can't call unWarpIGcard on " ++ show x
instance Plated IClafer
instance Plated PExp
instance Plated IExp
makeLenses ''IModule
makeLenses ''IClafer
makeLenses ''IElement
makeLenses ''ISuper
makeLenses ''IGCard
makeLenses ''PExp
makeLenses ''IExp
makeLenses ''IDecl