{-# LANGUAGE FlexibleInstances #-} module Language.C.DSL.Stat where import Language.C -- | An if statement with no else clause cif :: CExpr -> CStat -> CStat cif exp stat = CIf exp stat Nothing undefNode -- | An if statement with an else clause cifElse :: CExpr -> CStat -> CStat -> CStat cifElse exp th el = CIf exp th (Just el) undefNode -- | A while loop, the 'CExpr' is the looping condition. while :: CExpr -> CStat -> CStat while exp stat = CWhile exp stat False undefNode -- | A for loop, an example use -- -- > for(int "x" .= 1, 1, PlusPlus `pre` "x") -- > "printf"#[str "%d\n", "x"] for :: (CDecl, CExpr, CExpr) -> CStat -> CStat for (init, test, upd) block = CFor (Right init) (Just test) (Just upd) block undefNode -- | A for loop with no declarations. noDeclFor :: (CExpr, CExpr) -> CStat -> CStat noDeclFor (test, upd) block = CFor (Left Nothing) (Just test) (Just upd) block undefNode -- | A do while loop. doWhile :: CExpr -> CStat -> CStat doWhile exp stat = CWhile exp stat True undefNode cbreak :: CStat cbreak = CBreak undefNode ccont :: CStat ccont = CCont undefNode creturn :: CExpr -> CStat creturn = flip CReturn undefNode . Just cvoidReturn :: CStat cvoidReturn = CReturn Nothing undefNode liftE :: CExpr -> CStat liftE e = CExpr (Just e) undefNode class BlockLike a where intoB :: a -> CBlockItem instance BlockLike CStat where intoB = CBlockStmt instance BlockLike CExpr where intoB = intoB . liftE instance BlockLike CDecl where intoB = CBlockDecl block :: [CBlockItem] -> CStat block = flip (CCompound []) undefNode hBlock :: BlockLike a => [a] -> CStat hBlock = block . map intoB