module Language.Clafer.Intermediate.StringAnalyzer where
import Data.Tuple
import qualified Data.Map as Map
import Control.Monad.State
import Language.Clafer.Intermediate.Intclafer
astrModule :: IModule -> (IModule, Map.Map Int String)
astrModule imodule = (imodule{_mDecls = decls''}, flipMap strMap')
where
decls' = _mDecls imodule
(decls'', strMap') = runState (mapM astrElement decls') Map.empty
flipMap :: Map.Map String Int -> Map.Map Int String
flipMap = Map.fromList . map swap . Map.toList
astrClafer :: MonadState (Map.Map String Int) m => IClafer -> m IClafer
astrClafer (IClafer s isAbs gcrd' ident' uid' puid' super' reference' crd' gCard es) =
IClafer s isAbs gcrd' ident' uid' puid' super' reference' crd' gCard `liftM` mapM astrElement es
astrElement :: MonadState (Map.Map String Int) m => IElement -> m IElement
astrElement x = case x of
IEClafer clafer -> IEClafer `liftM` astrClafer clafer
IEConstraint isHard' pexp -> IEConstraint isHard' `liftM` astrPExp pexp
IEGoal isMaximize' pexp -> IEGoal isMaximize' `liftM` astrPExp pexp
astrPExp :: MonadState (Map.Map String Int) m => PExp -> m PExp
astrPExp (PExp (Just TString) pid' pos' exp') =
PExp (Just TInteger) pid' pos' `liftM` astrIExp exp'
astrPExp (PExp t pid' pos' (IFunExp op' exps')) = PExp t pid' pos' `liftM`
(IFunExp op' `liftM` mapM astrPExp exps')
astrPExp (PExp t pid' pos' (IDeclPExp quant' oDecls' bpexp')) = PExp t pid' pos' `liftM`
(IDeclPExp quant' oDecls' `liftM` (astrPExp bpexp'))
astrPExp x = return x
astrIExp :: MonadState (Map.Map String Int) m => IExp -> m IExp
astrIExp x = case x of
IFunExp op' exps' -> IFunExp op' `liftM` mapM astrPExp exps'
IStr str -> do
modify (\e -> Map.insertWith (flip const) str (Map.size e) e)
st <- get
return $ (IInt $ toInteger $ (Map.!) st str)
_ -> return x