content: -- $Id: Cpr001_imp.hs,v 1.1 2001/08/22 12:21:15 simonmar Exp $
  
  module Cpr001_imp where
  
  import Control.Applicative (Applicative(..))
  import Control.Monad (liftM, ap)
  
  data MS         = MS { instr    :: String
                       , pc       :: Int
                       , mem      :: String
                       , stack    :: String
                       , frames   :: [String]
                       , status   :: Maybe String
                       }
  
  
  newtype StateTrans s a = ST ( s -> (s, Maybe a))
  
  -- state monad with error handling
  -- in case of an error, the state remains
  -- as it is and Nothing is returned as value
  -- else execution continues
  
  instance Functor (StateTrans s) where
      fmap = liftM
  
  instance Applicative (StateTrans s) where
      pure v= ST (\s -> (s, Just v))
      (<*>) = ap
  
  instance Monad (StateTrans s) where
      (ST p) >>= k
          = ST (\s0 -> let
                       (s1, r0)   = p s0
                       in
                       case r0 of
                       Just v -> let
                                 (ST q) = k v
                                 in
                                 q s1
                       Nothing -> (s1, Nothing)
               )
  
  
  -- machine state transitions
  
  type MachineStateTrans  = StateTrans MS
  
  type MST = MachineStateTrans
  
  {-# NOINLINE setMTerminated #-}
  setMTerminated
      = ST (\ms -> (ms { status = Just "Terminated" }, Just ()))
  
  setMSvc call
      = ST (\ms -> (ms { status = Just "Service" }, Just ()))
  
  -- -------------------------------------------------------------------
  
  data Instr
      = LoadI             Int             -- load int const
      | SysCall           String          -- system call (svc)
  
  