{-# LANGUAGE OverloadedStrings #-}
module SMR.Prim.Op.Bool where
import SMR.Core.Exp
import SMR.Prim.Op.Base
import Data.Text (Text)
primOpsBool :: [PrimEval s Prim w]
primOpsBool
= [ primOpBool1 "not" "boolean negation" (\b -> not b)
, primOpBool2 "and" "boolean and" (&&)
, primOpBool2 "or" "boolean or" (||)
, primOpIf ]
primOpBool1
:: Name -> Text
-> (Bool -> Bool)
-> PrimEval s Prim w
primOpBool1 name desc fn
= PrimEval (PrimOp name) desc [PVal] fn'
where fn' _world as0
| Just (b1, []) <- takeArgBool as0
= return $ Just $ makeXBool (fn b1)
fn' _world _
= return $ Nothing
primOpBool2
:: Name -> Text
-> (Bool -> Bool -> Bool)
-> PrimEval s Prim w
primOpBool2 name desc fn
= PrimEval (PrimOp name) desc [PVal, PVal] fn'
where
fn' _world as0
| Just (b1, as1) <- takeArgBool as0
, Just (b2, []) <- takeArgBool as1
= return $ Just $ makeXBool (fn b1 b2)
fn' _world _
= return $ Nothing
primOpIf :: PrimEval s Prim w
primOpIf
= PrimEval
(PrimOp "if")
"boolean if-then-else operator"
[PVal, PExp, PExp] fn'
where
fn' _world as0
| Just (b1, as1) <- takeArgBool as0
, Just (x1, as2) <- takeArgExp as1
, Just (x2, []) <- takeArgExp as2
= return $ Just $ if b1 then x1 else x2
fn' _world _
= return $ Nothing