{-# LANGUAGE UndecidableInstances, TypeSynonymInstances, FlexibleInstances, GeneralizedNewtypeDeriving #-} module GenSym where import Control.Monad.State import Text.PrettyPrint import Util -- temps newtype Temp = Temp Int deriving (Eq, Ord, Enum) instance Show Temp where show (Temp i) = "t" ++ show i instance Pretty Temp where ppr t = text $ show t class Temporary a where temp :: Temp -> a instance Temporary Temp where temp = id -- labels newtype TempLabel = TempLabel Int deriving (Show, Eq, Ord, Enum) type Label = String mkLabel :: TempLabel -> Label mkLabel (TempLabel i) = "L" ++ show i instance Pretty Label where ppr l = text l -- the mutable state of the translation process data St = St { nextFreeTemp :: Temp -- next free temp , nextFreeLabel :: TempLabel } -- next free label initSt :: St initSt = St (Temp 1000) (TempLabel 0) -- class (Enum a, MonadState a m) => MonadGenSym m -- (too much abstraction:) class MonadSt m where nextTemp :: m Temp nextLabel :: m Label instance MonadState St m => MonadSt m where nextTemp = do St t l <- get put $ St (succ t) l return t nextLabel = do St t l <- get put $ St t (succ l) return $ mkLabel l