content: {-# LANGUAGE DeriveDataTypeable #-}
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  Language.C.Syntax.Ops
  -- Copyright   :  (c) 2008 Benedikt Huber
  -- License     :  BSD-style
  -- Maintainer  : benedikt.huber@gmail.com
  -- Stability   : experimental
  -- Portability : ghc
  --
  -- Unary, binary and asssignment operators. Exported via AST.
  -----------------------------------------------------------------------------
  module Language.C.Syntax.Ops (
  -- * Assignment operators
  CAssignOp(..),
  assignBinop,
  -- * Binary operators
  CBinaryOp(..),
  isCmpOp,
  isPtrOp,
  isBitOp,
  isLogicOp,
  -- * Unary operators
  CUnaryOp(..),
  isEffectfulOp
  )
  where
  import Data.Generics
  -- | C assignment operators (K&R A7.17)
  data CAssignOp = CAssignOp
                 | CMulAssOp
                 | CDivAssOp
                 | CRmdAssOp              -- ^ remainder and assignment
                 | CAddAssOp
                 | CSubAssOp
                 | CShlAssOp
                 | CShrAssOp
                 | CAndAssOp
                 | CXorAssOp
                 | COrAssOp
                 deriving (Eq,Ord,Show,Data,Typeable)
  
  assignBinop :: CAssignOp -> CBinaryOp
  assignBinop CAssignOp = error "direct assignment has no binary operator"
  assignBinop CMulAssOp = CMulOp
  assignBinop CDivAssOp = CDivOp
  assignBinop CRmdAssOp = CRmdOp
  assignBinop CAddAssOp = CAddOp
  assignBinop CSubAssOp = CSubOp
  assignBinop CShlAssOp = CShlOp
  assignBinop CShrAssOp = CShrOp
  assignBinop CAndAssOp = CAndOp
  assignBinop CXorAssOp = CXorOp
  assignBinop COrAssOp  = COrOp
  
  -- | C binary operators (K&R A7.6-15)
  --
  data CBinaryOp = CMulOp
                 | CDivOp
                 | CRmdOp                 -- ^ remainder of division
                 | CAddOp
                 | CSubOp
                 | CShlOp                 -- ^ shift left
                 | CShrOp                 -- ^ shift right
                 | CLeOp                  -- ^ less
                 | CGrOp                  -- ^ greater
                 | CLeqOp                 -- ^ less or equal
                 | CGeqOp                 -- ^ greater or equal
                 | CEqOp                  -- ^ equal
                 | CNeqOp                 -- ^ not equal
                 | CAndOp                 -- ^ bitwise and
                 | CXorOp                 -- ^ exclusive bitwise or
                 | COrOp                  -- ^ inclusive bitwise or
                 | CLndOp                 -- ^ logical and
                 | CLorOp                 -- ^ logical or
                 deriving (Eq,Ord,Show,Data,Typeable)
  
  isCmpOp :: CBinaryOp -> Bool
  isCmpOp op = op `elem` [ CLeqOp, CGeqOp, CLeOp, CGrOp, CEqOp, CNeqOp ]
  
  isPtrOp :: CBinaryOp -> Bool
  isPtrOp op = op `elem` [ CAddOp, CSubOp ]
  
  isBitOp :: CBinaryOp -> Bool
  isBitOp op = op `elem` [ CShlOp, CShrOp, CAndOp, COrOp, CXorOp ]
  
  isLogicOp :: CBinaryOp -> Bool
  isLogicOp op = op `elem` [ CLndOp, CLorOp ]
  
  -- | C unary operator (K&R A7.3-4)
  --
  data CUnaryOp = CPreIncOp               -- ^ prefix increment operator
                | CPreDecOp               -- ^ prefix decrement operator
                | CPostIncOp              -- ^ postfix increment operator
                | CPostDecOp              -- ^ postfix decrement operator
                | CAdrOp                  -- ^ address operator
                | CIndOp                  -- ^ indirection operator
                | CPlusOp                 -- ^ prefix plus
                | CMinOp                  -- ^ prefix minus
                | CCompOp                 -- ^ one's complement
                | CNegOp                  -- ^ logical negation
                deriving (Eq,Ord,Show,Data,Typeable)
  
  isEffectfulOp :: CUnaryOp -> Bool
  isEffectfulOp op = op `elem` [ CPreIncOp, CPreDecOp, CPostIncOp, CPostDecOp ]
  