-- -- Copyright (c) 2005 Don Stewart - http://www.cse.unsw.edu.au/~dons -- Sean Seefried -- Stefan Wehr -- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html) -- module FSM where import CR import Syntax import ServerCom import Logging import Pretty data State = SState SendState | RState RecvState | FinalState deriving Show data SendState = SendState { sstate_name :: String , sstate_data :: SendMessage , sstate_trans :: DummyTrans } instance Show SendState where show s = "" instance Show RecvState where show s = "" data SelectorResult = forall a. SelectorResult (a, Trans a) | NoSelectorResult type SelectorFunction = RecvMessage -> SelectorResult data RecvState = RecvState { rstate_name :: String , rstate_selectFun :: SelectorFunction , rstate_parseflag :: ParseStateFlag } type Trans a = a -> CR State type DummyTrans = CR State runFSM :: State -> CR () runFSM (SState s) = do sendToServer (sstate_data s) s' <- sstate_trans s debug $ "State transition from " ++ show s ++ " to " ++ show s' runFSM s' runFSM (RState s) = do let pst = rstate_parseflag s msg <- receiveFromServer pst case rstate_selectFun s msg of SelectorResult (m, trans) -> do s' <- trans m debug $ "State transition from " ++ show s ++ " to " ++ show s' runFSM s' NoSelectorResult -> do fatal $ "No transition from " ++ show s ++ " on incoming message: " ++ showPpr msg ++ "\nraw data: " ++ show msg runFSM FinalState = do debug "FSM reached final state" return ()