{-# LANGUAGE OverloadedStrings #-}

module Op ( FUn (..)
          , FBin (..)
          , IUn (..)
          , BUn (..)
          , IBin (..)
          , BBin (..)
          , IRel (..)
          , FRel (..)
          ) where

import           Prettyprinter (Pretty (..))

data FUn = FSqrt | FLog | FSin | FCos | FAbs

data IUn = IEven | IOdd

data BUn = BNeg

data FBin = FPlus | FMinus | FTimes | FDiv | FMax | FMin | FExp

data BBin = AndB | OrB | XorB

data IBin = IPlus | IMinus | ITimes | IAsr | IMax | IMin | IDiv | IAsl | IRem | BI !BBin

data IRel = IEq | INeq | IGt | ILt | ILeq | IGeq
data FRel = FEq | FNeq | FGt | FLt | FLeq | FGeq

instance Pretty IRel where
    pretty :: forall ann. IRel -> Doc ann
pretty IRel
IEq  = Doc ann
"="; pretty IRel
INeq = Doc ann
"!="; pretty IRel
IGt  = Doc ann
">"
    pretty IRel
ILt  = Doc ann
"<"; pretty IRel
ILeq = Doc ann
"≤"; pretty IRel
IGeq = Doc ann
"≥"

instance Pretty FRel where
    pretty :: forall ann. FRel -> Doc ann
pretty FRel
FEq = Doc ann
"="; pretty FRel
FNeq = Doc ann
"!="; pretty FRel
FGt = Doc ann
">"
    pretty FRel
FLt = Doc ann
"<"; pretty FRel
FLeq = Doc ann
"≤"; pretty FRel
FGeq = Doc ann
"≥"

instance Pretty BUn where
    pretty :: forall ann. BUn -> Doc ann
pretty BUn
BNeg = Doc ann
"¬"

instance Pretty BBin where
   pretty :: forall ann. BBin -> Doc ann
pretty BBin
AndB = Doc ann
"∧"; pretty BBin
XorB = Doc ann
"⊻"; pretty BBin
OrB = Doc ann
"∨"

instance Pretty IBin where
    pretty :: forall ann. IBin -> Doc ann
pretty IBin
IPlus  = Doc ann
"+"
    pretty IBin
IMinus = Doc ann
"-"
    pretty IBin
ITimes = Doc ann
"*"
    pretty IBin
IDiv   = Doc ann
"div"
    pretty IBin
IAsl   = Doc ann
"asl"; pretty IBin
IAsr   = Doc ann
"asr"
    pretty IBin
IMax   = Doc ann
"max"; pretty IBin
IMin   = Doc ann
"min"
    pretty IBin
IRem   = Doc ann
"rem"
    pretty (BI BBin
p) = BBin -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. BBin -> Doc ann
pretty BBin
p

instance Pretty FBin where
    pretty :: forall ann. FBin -> Doc ann
pretty FBin
FPlus  = Doc ann
"+";
    pretty FBin
FMinus = Doc ann
"-"
    pretty FBin
FTimes = Doc ann
"*"
    pretty FBin
FDiv   = Doc ann
"%"
    pretty FBin
FExp   = Doc ann
"^"
    pretty FBin
FMax   = Doc ann
"max"
    pretty FBin
FMin   = Doc ann
"min"

instance Pretty FUn where
    pretty :: forall ann. FUn -> Doc ann
pretty FUn
FSqrt = Doc ann
"sqrt"
    pretty FUn
FLog  = Doc ann
"log"
    pretty FUn
FSin  = Doc ann
"sin"; pretty FUn
FCos  = Doc ann
"cos"
    pretty FUn
FAbs  = Doc ann
"abs"

instance Pretty IUn where
    pretty :: forall ann. IUn -> Doc ann
pretty IUn
IEven = Doc ann
"even"; pretty IUn
IOdd = Doc ann
"odd"