module Language.GuardedCommands.Extended
(
ExtendedGCL (..)
, pExtendedGCL
) where
import Control.Applicative
import Data.Data
import Text.Parser.Token
import Language.GuardedCommands
data ExtendedGCL name ty expr
= Declare [(name, ty)] (ExtendedGCL name ty expr)
| Assign [(name, expr)]
| Assume expr
| Assert expr
| GCL (GCL (ExtendedGCL name ty expr) expr)
deriving (Eq,Data,Typeable)
pExtendedGCL
:: (Monad m, TokenParsing m)
=> m name
-> m ty
-> m expr
-> m (ExtendedGCL name ty expr)
pExtendedGCL pName pType pExpr = pSelf
where
pSelf = (\_ -> Declare)
<$> symbol "declare" <*> commaSep1 ((,) <$> pName <* symbol ":" <*> pType)
<* symbol "in" <*> pSelf
<|> (\_ -> Assume) <$> symbol "assume" <*> pExpr
<|> (\_ -> Assert) <$> symbol "assert" <*> pExpr
<|> (processAssign =<< ((,) <$> commaSep1 pName <* symbol ":=" <*> commaSep1 pExpr))
<|> GCL <$> pGCL pSelf pExpr
processAssign (lvs, rvs)
| length lvs == length rvs = pure . Assign $ zip lvs rvs
| True = empty