module CsoundExpr.Translator.Cs.CsBoolean (CsBool)
where
import Data.Boolean
import CsoundExpr.Translator.Cs.CsTree
import CsoundExpr.Translator.ExprTree.ExprTree
mkAnd, mkOr :: CsTree -> CsTree -> CsTree
mkAnd a b = pure (oprInfix "&&") [a, b]
mkOr a b = pure (oprInfix "||") [a, b]
mkComp :: CompOp -> CsTree -> CsTree -> CsTree
mkComp op a b = pure (oprInfix $ show op) [a, b]
mkIf :: CsTree -> CsTree -> CsTree -> CsTree
mkIf cond th el = pure ifOpr [cond, th, el]
oprInfix :: Name -> CsExpr
oprInfix name = opr ["(", name, ")"]
ifOpr :: CsExpr
ifOpr = opr ["(", "?", ":",")"]
data CsBool = CsBPrim CsComp
| CsTrue
| CsFalse
| CsNot CsBool
| CsAnd CsBool CsBool
| CsOr CsBool CsBool
data CsComp = CsComp CompOp CsTree CsTree
data CompOp = CsEq | CsNeq | CsLt | CsGt | CsElt | CsEgt
instance Show CompOp where
show x = case x of
CsEq -> "=="
CsNeq -> "!="
CsLt -> "<"
CsGt -> ">"
CsElt -> "<="
CsEgt -> ">="
notCompOp :: CompOp -> CompOp
notCompOp x = case x of
CsEq -> CsNeq
CsNeq -> CsEq
CsLt -> CsEgt
CsGt -> CsElt
CsElt -> CsGt
CsEgt -> CsLt
instance Boolean CsBool where
true = CsTrue
false = CsFalse
notB = CsNot
a &&* b = case (a, b) of
(CsTrue, _) -> b
(CsFalse, _) -> CsFalse
(_, CsTrue ) -> a
(_, CsFalse) -> CsFalse
_ -> CsAnd a b
a ||* b = case (a, b) of
(CsTrue, _) -> CsTrue
(CsFalse, _) -> b
(_, CsTrue ) -> CsTrue
(_, CsFalse) -> a
_ -> CsOr a b
data Ctx = N | P
elimNots :: Ctx -> CsBool -> CsBool
elimNots P x =
case x of
CsNot a -> elimNots N a
CsAnd a b -> CsAnd (elimNots P a) (elimNots P b)
CsOr a b -> CsOr (elimNots P a) (elimNots P b)
_ -> x
elimNots N x =
case x of
CsBPrim (CsComp op a b) -> CsBPrim (CsComp (notCompOp op) a b)
CsTrue -> CsFalse
CsFalse -> CsTrue
CsNot a -> elimNots P a
CsAnd a b -> CsOr (elimNots N a) (elimNots N b)
CsOr a b -> CsAnd (elimNots N a) (elimNots N b)
instance IfB CsBool CsTree where
ifB cond a b = let cond' = elimNots P cond
in case cond' of
CsTrue -> a
CsFalse -> b
CsNot c -> ifB c b a
_ -> mkIf (getCondCsTree cond') a b
getCondCsTree :: CsBool -> CsTree
getCondCsTree x =
case x of
CsBPrim a -> getCompCsTree a
CsAnd a b -> mkAnd (getCondCsTree a) (getCondCsTree b)
CsOr a b -> mkOr (getCondCsTree a) (getCondCsTree b)
getCompCsTree :: CsComp -> CsTree
getCompCsTree (CsComp op a b) = mkComp op a b
bOp :: CompOp -> CsTree -> CsTree -> CsBool
bOp op a b = CsBPrim $ CsComp op a b
instance EqB CsBool CsTree where
(==*) = bOp CsEq
(/=*) = bOp CsNeq
instance OrdB CsBool CsTree where
(<*) = bOp CsLt
(>*) = bOp CsGt
(<=*) = bOp CsElt
(>=*) = bOp CsEgt