content: module Ivory.Language.IIntegral where
  
  import Ivory.Language.Sint
  import Ivory.Language.Type
  import Ivory.Language.IBool
  import Ivory.Language.Uint
  import qualified Ivory.Language.Syntax.AST as I
  
  --------------------------------------------------------------------------------
  
  -- | Integral, without the baggage from Haskell (i.e., supertypes of 'Real' and
  -- 'Enum'). Defines Euclidian division (rather than truncated division). See
  -- http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.74.8522. Notable
  -- properties, beyond the normal div/rem properties, are that
  --
  -- The remainder is always non-negative.
  -- For d1 < 0, @d0 `iDiv` (-d1) == -(d0 `iDiv` d1)@.
  -- For d1 < 0, @d0 .% (-d1) == d0 .% d1@.
  --
  -- N.B. `mod` and `rem` are equal if both args are positive, and C has no `mod`
  -- operator (only `rem`). In Haskell and C, both `mod` and `rem` may return
  -- negative values. Furthermore, before C99, the result of `rem` is
  -- implementation-defined.
  class (IvoryExpr a, IvoryOrd a , Num a) => IvoryIntegral a where
  
    -- | Euclidean division.
    iDiv :: a -> a -> a
    iDiv d0 d1 = (r <? 0) ? ((d1 >? 0) ? (q-1,q+1),q)
      where
      q = wrapExpr (I.ExpOp I.ExpDiv [unwrapExpr d0, unwrapExpr d1])
      r = iRem d0 d1
  
    -- | Euclidean remainder.
    (.%) :: a -> a -> a
    d0 .% d1 = (r <? 0) ? ((d1 >? 0) ? (r+d1,r-d1),r)
      where
      r = iRem d0 d1
  
  (./) :: IvoryIntegral a => a -> a -> a
  (./) = iDiv
  
  -- XXX Dont' export
  iRem :: IvoryIntegral a => a -> a -> a
  iRem d0 d1 = wrapExpr (I.ExpOp I.ExpMod [unwrapExpr d0, unwrapExpr d1])
  
  --------------------------------------------------------------------------------
  
  instance IvoryIntegral Sint8
  instance IvoryIntegral Sint16
  instance IvoryIntegral Sint32
  instance IvoryIntegral Sint64
  instance IvoryIntegral Uint8
  instance IvoryIntegral Uint16
  instance IvoryIntegral Uint32
  instance IvoryIntegral Uint64
  
  --------------------------------------------------------------------------------
  