alpha-1.0.15: src/Compile/Monad.hs
{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, NoMonomorphismRestriction #-}
module Compile.Monad where
import My.Control.Monad.State
import My.Control.Monad.WriterAcc
import ID
import PCode.Instruction
import Data.Map
data CompileState = CS {
infoStack :: [(Int,[Int],Int,Maybe ID)],
locals :: Map ID ID
}
infoStack_ = View (infoStack,\s cs -> cs { infoStack = s })
locals_ = View (locals,\s cs -> cs { locals = s })
newtype CompileT m a = CM { runCM :: StateT CompileState (WriterAccT [Instruction] (Sum Int) m) a }
deriving (Monad,MonadFix,MonadState CompileState,MonadWriter [Instruction])
instance MonadTrans CompileT where
lift = CM . lift . lift
getPos = CM (liftM getSum (lift getAcc))
runCompileT (CM m) locals = runWriterAccT (evalStateT m (CS [] locals))
pushInfo = modifying infoStack_ . (:)
popInfo = viewState infoStack_ (\l -> case l of
(h:t) -> (h,t)
[] -> error "Invalid use of Axioms <- or -> outside of a choose expression")
topInfo = getting (infoStack_ >>> f_ head)
withInfo f = popInfo >>= \i -> f i >>= \ret -> pushInfo i >> return ret