module Control.Operate.Types ( OperateDoExp (..) , OpdoStmt (..) , OperatorDirection (..) , OpdoOperatorInfo (..) , OpdoStatements (..) , runOpdo ) where import Language.Haskell.TH data OpdoOperatorInfo = OpdoOperatorInfo { getOperatorDirection :: OperatorDirection , getOperatorExpression :: Exp } deriving (Eq, Ord, Show) data OpdoStatements = OpdoStatements { getOpCmds :: [OpdoStmt] , getOpCmdLastOne :: Exp } deriving (Eq, Ord, Show) data OperateDoExp = OperateDoExp { opdoOperator :: OpdoOperatorInfo , opdoStatements :: OpdoStatements } deriving (Eq, Ord, Show) data OpdoStmt = OpdoExpS Exp deriving (Show, Ord, Eq) data OperatorDirection = LeftOperator | RightOperator deriving (Eq, Ord, Show, Enum) runOpdo :: OperateDoExp -> Exp runOpdo (OperateDoExp (OpdoOperatorInfo LeftOperator opExp) (OpdoStatements stmts expr)) = go stmts where go [] = expr go ~(OpdoExpS x:xs) = AppE (AppE opExp $ go' xs x) expr go' [] cont = cont go' ~(OpdoExpS x:xs) cont = go' xs $ AppE (AppE opExp cont) x runOpdo (OperateDoExp (OpdoOperatorInfo RightOperator opExp) (OpdoStatements stmts expr)) = go stmts where go [] = expr go ~(OpdoExpS x:xs) = AppE (AppE opExp x) $ go xs